LTE PDSCH/PUSCH Resource Allocation
The purpose of this tutorial is to show you how to allocate resources for PDSCH/PUSCH manually instead of letting gNB/eNB automatically schedule them depending on the situation (e.g, depending on amount the data from higher layer, radio link quality etc).
In default configuration, Amarisoft eNB/gNB schedule PHY/MAC resources automatically based on various factors like IP layer throughput and radio link quality (e.g, amount of CRC(i.e, retx), CSI report from UE (i.e, CQI, RI), phr report from UE). But sometimes you may want to allocate the PHY/MAC resources as you like regardless of other conditions mentioned above. You can specify following PHY / MAC resources manually as you want.
- RB Allocation : Start of RB and The number of RBs for each subframe for both PDSCH and PUSCH
- MCS : MCS for each subframe for both PDSCH and PUSCH
- I want to test the physical layer throughput at a specific condition (e.g, with a specific number of RBs and MCS) without using IP traffic tool (e.g, iperf etc)
- When I want to do some Radio Link Quality troubleshoot, I usually lower MCS manually until I get zero BLER (zero retx) in 't' command and then change connection enviorment (e.g, distance between UE and antenna, direction of antenna, antenna connection vs cable connection etc) and increase MCS step by step and see if any of those setup adjustment improve retx rate at a certain MCS
Table of Contents
- LTE PDSCH/PUSCH Resource Allocation
- Introduction
- Summary of the Tutorial
- Test Setup
- Key Configuration Parameters
- Test 1 : PDSCH Resource Allocation
- Test 2 : PUSCH Resource Allocation
- Configuration
- Perform the Test
- Log Analysis
- Sub Test 1 : PUSCH Resource Allocation with Fixed RB
- Sub Test 2 : PUSCH Resource Allocation with Fixed RB per Subframe
- Sub Test 3 : PUSCH Resource Allocation with Full RB
- Tips
Introduction
Manual resource allocation for Physical Downlink Shared Channel (PDSCH) and Physical Uplink Shared Channel (PUSCH) in cellular networks offers granular control over PHY/MAC layer parameters, bypassing the typical dynamic scheduling performed by the gNB (5G NR base station) or eNB (LTE base station). In standard operational scenarios, Amarisoft eNB/gNB automatically manages resource distribution based on real-time metrics such as IP layer throughput, link adaptation feedback (e.g., Channel Quality Indicator (CQI), Rank Indicator (RI)), Power Headroom Reports (PHR), and Hybrid Automatic Repeat Request (HARQ) statistics (e.g., CRC and retransmissions). However, there are use cases where direct manual intervention is desirable—such as precise throughput benchmarking, radio link quality troubleshooting, or customized test scenarios. By specifying parameters like Resource Block (RB) allocation (defining the start RB and number of RBs per subframe) and Modulation and Coding Scheme (MCS) for each subframe, engineers and researchers can simulate specific radio conditions, bypass upper-layer traffic generators, and systematically analyze performance at the physical layer. This approach is crucial for validating PHY/MAC implementations, optimizing link adaptation strategies, and isolating variables in controlled test environments. Manual resource configuration thus plays a significant role in R&D, performance tuning, and quality assurance within the broader radio access network (RAN) ecosystem, complementing the automated, adaptive scheduling mechanisms that typically govern live networks.
-
Context and Technology Overview
- Amarisoft eNB/gNB platforms provide flexible, software-defined LTE and 5G NR base station functionality, supporting both automated and manual resource scheduling.
- PDSCH (downlink) and PUSCH (uplink) are the primary shared channels in LTE/NR, responsible for user data transmission, with resource allocation critical for throughput and reliability.
- Automated scheduling leverages radio feedback and higher-layer demands, while manual allocation allows explicit control over parameters such as RB assignment and MCS selection.
- Manual resource control is commonly used in R&D, conformance testing, and physical layer performance validation, providing a deterministic environment for experimentation.
-
Relevance and Importance of the Tutorial Topic
- Enables precise throughput measurement and benchmarking under known, reproducible radio conditions, without requiring IP traffic tools.
- Facilitates radio link troubleshooting by allowing stepwise adjustment of MCS and RB allocations to observe their impact on block error rate (BLER) and retransmissions.
- Supports advanced research, algorithm development, and root cause analysis by decoupling PHY/MAC behavior from adaptive scheduling mechanisms.
- Critical for validating device and network performance in controlled testbeds, prior to field deployment.
-
What Learners Will Gain
- Understanding of manual resource allocation mechanisms on Amarisoft eNB/gNB platforms.
- Practical skills in configuring RB and MCS parameters for both PDSCH and PUSCH on a per-subframe basis.
- Insights into PHY/MAC layer performance analysis, including methods for throughput and BLER optimization.
- Experience in setting up targeted experiments for radio link quality assessment and troubleshooting.
-
Prerequisite Knowledge and Skills
- Basic understanding of LTE/5G NR radio access network architecture and protocol stack, especially the PHY and MAC layers.
- Familiarity with Amarisoft eNB/gNB configuration and operational environment.
- Knowledge of key radio parameters: Resource Block (RB), Modulation and Coding Scheme (MCS), subframe structure.
- Experience with command-line tools and network testing methodologies is beneficial.
Summary of the Tutorial
This tutorial provides step-by-step procedures for manual allocation of PDSCH and PUSCH physical resources in LTE using Amarisoft configuration files, including several subtests exploring different resource allocation scenarios.
-
Test Setup:
- Low layer testing environment using a SIM card supplied with the system.
- No advanced IP configuration needed for these procedures.
-
Key Configuration Parameters:
- Manual resource allocation is controlled by parameters such as force_dl_schedule, force_full_bsr, pusch_fixed_rb_forced, pdsch_mcs, pdsch_fixed_rb_alloc, pdsch_fixed_rb_start, pdsch_fixed_l_crb, pusch_mcs, pusch_fixed_rb_alloc, pusch_fixed_rb_start, and pusch_fixed_l_crb.
-
Test 1: PDSCH Resource Allocation
-
Configuration:
- Use enb-pdsch-resources.cfg derived from enb.default.cfg.
- Set N_RB_DL to 100 for 20 MHz bandwidth.
- Manually configure PDSCH allocation using parameters: force_dl_schedule, pdsch_mcs, pdsch_fixed_rb_alloc, pdsch_fixed_rb_start, pdsch_fixed_l_crb.
-
Test Steps:
- Verify cell configuration with 'cell phy' and 'cell' commands.
- Start trace logging with the 't' command.
-
Log Analysis:
- Confirm resource allocation in log outputs and graphical RB plots.
- Observe that user traffic PDSCH allocation may be reduced if it shares a subframe with SIB PDSCH.
-
Sub Test 1: PDSCH Resource Allocation per Subframe
- Use enb-pdsch-resources-subframe.cfg.
- Configure PDSCH resource parameters as arrays to assign different resources per subframe.
- Visualize subframe-specific allocation using RB plots.
-
Configuration:
-
Test 2: PUSCH Resource Allocation
-
Configuration:
- Use enb-pusch-resources.cfg based on enb.default.cfg.
- Set N_RB_DL to 100 and force_full_bsr: true to schedule PUSCH in every possible UL subframe.
-
Test Steps:
- Validate cell configuration using 'cell phy' and 'cell'.
- Start trace logging using the 't' command.
-
Log Analysis:
- Check resource allocation through logs and RB map plots.
- Note that maximal RB allocation is constrained by PUCCH reservation and specific RB allocation rules.
-
Sub Test 1: PUSCH Resource Allocation with Fixed RB
- Use enb-pusch-resources-fixedRB.cfg.
- Allocate identical physical resources for each PUSCH transmission using single-value parameters.
- Ensure pusch_fixed_l_crb meets specific mathematical criteria (2a * 3b * 5c).
-
Sub Test 2: PUSCH Resource Allocation with Fixed RB per Subframe
- Use enb-pusch-resources-subframe.cfg.
- Assign different resources to each PUSCH subframe by configuring array values for parameters.
- Again, pusch_fixed_l_crb must comply with specific value criteria.
-
Sub Test 3: PUSCH Resource Allocation with Full RB
- Use enb-ul-full-rb.cfg.
- Enable pusch_fixed_rb_forced: true and set pusch_fixed_l_crb to maximum for the bandwidth.
- This config is intended for maximum UL throughput in single-UE scenarios, allocating all RBs including those typically reserved for PUCCH.
-
Configuration:
-
Tips: Interpretation of Resource Allocation Array in TDD
- Resource allocation arrays map to absolute slot/subframe numbers, not available slots only.
- Array elements corresponding to DL or special slots are ignored for PUSCH scheduling.
- Scheduling in special slots requires enabling the partial_slots parameter.
- In LTE, arrays are indexed by subframe; in NR, by slot (i.e., by TTI).
- A false in pusch_fixed_rb_alloc means eNB/gNB determines RBs dynamically, not that scheduling is stopped.
The tutorial guides users through the process of configuring and verifying manual resource allocation for both PDSCH and PUSCH, providing methodologies for both static and dynamic (per subframe) resource assignments, and clarifies interpretation of configuration arrays for TDD scenarios.
Test Setup
Test setup for this tutorial is as shown below. This is just for low layer testing, you may not need any complicated IP layer setup.
- SIM Card used in this tutorial is the one delivered with the system as it is.
- If you want to change the configuration, The tutorial Configuration Guide would help

Key Configuration Parameters
Followings are important configuration parameters for this tutorial. You may click on the items for the descriptions from Amarisoft documents.
- force_dl_schedule
- force_full_bsr
- pusch_fixed_rb_forced
- pdsch_mcs
- pdsch_fixed_rb_alloc
- pdsch_fixed_rb_start
- pdsch_fixed_l_crb
- pusch_mcs
- pusch_fixed_rb_alloc
- pusch_fixed_rb_start
- pusch_fixed_l_crb
Test 1 : PDSCH Resource Allocation
This test is to show how to allocates PDSCH resource manually in which you can allocate PDSCH resources in configuration file.
Configuration
The configuration shown here is common configuration for all the subtests belonging to Test 1 and I will not show this configuration repeatedly for every subtest.
I have used enb-pdsch-resources.cfg which is copied and modified from enb.default.cfg

I am using the default mme, ims config as shown below.

In enb-pdsch-resources.cfg, it is configured as follows.
The bandwidth is set to 20 Mhz by setting N_RB_DL to 100.

In cell configuration, the PDSCH resource is allocated manually by setting force_dl_schedule, pdsch_mcs, pdsch_fixed_rb_alloc, pdsch_fixed_rb_start, pdsch_fixed_l_crb.

Perform the Test
Check out cell configuration with 'cell phy' and 'cell', and make it sure that the cell is configured as intended.

Start printing trace log with 't' command.

Log Analysis
You can confirm the resource allocation either in the log print text and in graphical format.
You can check out the physical layer scheduling and resource allocation for SIB PDSCH. In case of SIB PDSCH, harq is marked as 'si'

You can also check out user traffic PDSCH in PHY log. Even though the number of RBs for the user traffic PDSCH is configured to max value, it gets reduced a little bit when it is transmitted in the same subframe as SIB PDSCH.

You can visualize the physical resource allocation for SIB PDSCH easily by RB plot.

You can also visualize the physical resource allocation for SIB PDSCH easily by RB plot.

Sub Test 1 : PDSCH Resource Allocation per Subframe
This subtest shows how to allocate different physical resources for every subframe of PDSCH transmission.
I have used enb-pdsch-resources-subframe.cfg which is copied and modified from enb.default.cfg
In cell configuration, the PDSCH resource is allocated manually by setting force_dl_schedule, pdsch_mcs, pdsch_fixed_rb_alloc, pdsch_fixed_rb_start, pdsch_fixed_l_crb. The main point for this test is that pdsch_mcs, pdsch_fixed_rb_alloc, pdsch_fixed_rb_start, pdsch_fixed_l_crb are in array format. Each elements in the array applies to each subframe.

The allocated resources for PDSCH in this subtest is visualized in RB plot.

Test 2 : PUSCH Resource Allocation
This test is to show how to allocates PUSCH resource manually in which you can allocate PUSCH resources in configuration file.
Configuration
The configuration shown here is common configuration for all the subtests belonging to Test 1 and I will not show this configuration repeatedly for every subtest.
I have used enb-pusch-resources.cfg which is copied and modified from enb.default.cfg

I am using the default mme, ims config as shown below.

In enb-pusch-resources.cfg, it is configured as follows.
The bandwidth is set to 20 Mhz by setting N_RB_DL to 100.

Set force_full_bsr : true which means 'schedule PUSCH at every possible UL subframe'. Since other parameters (e.g, mcs) is not configured, the different mcs will be applied depending on radio link quality.

Perform the Test
Check out cell configuration with 'cell phy' and 'cell', and make it sure that the cell is configured as intended.

Start printing trace log with 't' command.

Log Analysis
You can confirm the resource allocation either in the log print text. You would notice that the RB is never allocated to max possible value because PUCCH resources is reserved and not used for PUSCH.

You can check on uplink resourace allocation in RB map. You see here that a certain range of the resource blocks at both end of the frequency domain is not scheduled for PUSCH. This is because eNB wants to reserve the region for PUCCH or UL number of RB should be 2^a * 3^b * 5^c where a,b,c is 0 or positive integers.

Sub Test 1 : PUSCH Resource Allocation with Fixed RB
This subtest shows how to allocate same physical resources for every subframe of PUSCH transmission
I have used enb-pusch-resources-fixedRB.cfg which is copied and modified from enb.default.cfg
Same physical resources will be applied to every PUSCH transmission by pusch_mcs, pusch_fixed_rb_alloc, pusch_fixed_rb_start, pusch_fixed_l_crb with single value (not Array). You need to pay attention to pusch_fixed_l_crb since it should meet the criteria of 2^a * 3^b * 5^c where a,b,c are 0 or positive integers.

The allocated resources for PUSCH in this subtest is in RB map plot. You see that every PUSCH is allocated with the same number of RBs as set in the configuration file.

Sub Test 2 : PUSCH Resource Allocation with Fixed RB per Subframe
This subtest shows how to allocate different physical resources for every subframe of PUSCH transmission
I have used enb-pusch-resources-subframe.cfg which is copied and modified from enb.default.cfg
Different physical resources can be applied to every PUSCH transmission by pusch_mcs, pusch_fixed_rb_alloc, pusch_fixed_rb_start, pusch_fixed_l_crb with an array (not a single value). You need to pay attention to pusch_fixed_l_crb since it should meet the criteria of 2^a * 3^b * 5^c where a,b,c are 0 or positive integers.

The allocated resources for PUSCH in this subtest is in RB map plot. You see that every PUSCH is allocated with the same number of RBs as set in the configuration file.

Sub Test 3 : PUSCH Resource Allocation with Full RB
This subtest shows how to allocate full physical resources for PUSCH. 'Full Physical Resource' mean the full UL RBs including the resources reserved for PUCCH. Main purpose of this configuration is to provide the maximun possible UL throughput as you can achieve from other callbox which supports single UE only. It implies that this configuration would work only when single UE is connected.
I have used enb-ul-full-rb.cfg which is copied and modified from enb.default.cfg
Same physical resources will be applied to every PUSCH transmission by pusch_mcs, pusch_fixed_rb_alloc, pusch_fixed_rb_start, pusch_fixed_l_crb with single value (not Array). The key point in this configuration is that you need to set pusch_fixed_rb_forced: true which enables the full RB allocation including the area reserved for PUCCH and set pusch_fixed_l_crb to max RB for the channel bandwidth.

The allocated resources for PUSCH in this subtest is in RB map plot. You see that every PUSCH is allocated with the same number of RBs as set in the configuration file which is full RB(100 RB in this case).

Tips
Interpretation of Resource Allocation Array in TDD
It may be a little bit confusing to interpret the resource schedule array in TDD. So I want to clarify a few things with an example here. Note that this example is for PUSCH scheduling.
force_full_bsr: true,
pusch_fixed_rb_alloc: [ true,true,false,true,true,true,true,true,true,true ],
pusch_fixed_rb_start: [ 1,2,3,4,5,6,7,8,9,10],
pusch_fixed_l_crb: [ 11,12,13,14,15,16,17,18,19,20],
Let me explain a few things in Q&A form.
Q1 : Is the index of the array maps to absolute slot number ? or relative available slot ? For example, the 'false' (the third slot) of pusch_fixed_rb_alloc in this example mean 'slot #2 within the continguous 10 slots(size of the array)' or 'third available slot regardless of absolute position' ?
A1: It indicates absolute position. So the 'false' (the third slot) of pusch_fixed_rb_alloc in this example indicates the slot #2 of the contiguous 10 slots(size of the array)
Q2 : Then what would happen for the array index mapped to downlink slot ? For example, How the first element of pusch_fixed_rb_alloc, pusch_fixed_rb_start, pusch_fixed_l_crb of the array works (assuming that the first slot is configured as downlink in TDD pattern).
A2 : It is get ignored.
Q3 : What would happen for the array index mapped to special slot(partial slot) ?
A3 : PUSCH in partial slot is not scheduled in default configuration. If you want to schedule PUSCH in special slot (or special subframe), you need to set the parameter partial_slots
Q4 : Is value 0 in pusch_fixed_l_crb allowed ?
A4 : It is allowed for LTE, but not allowed in NR with this parameter. (
Q5 : What does each element in the array indicates ? Does it indicates 'slot' or 'subframe' ?
A5 : In LTE, it indicates 'subframe', in NR it indicates 'slot'. Simply put, it indicates a TTI.
Q6: what is the meaning of 'false' in pusch_fixed_rb_alloc ? For example, in this example pusch_fixed_rb_alloc: [ true,true,false,true,true,true,true,true,true,true ] what eNB/gNB would do at slot #2 ('false') ? does it stop PUSCH scheduling ? or it DOES schedule PUSCH with the best fit available RBs ?
A6 : It DOES schedule PUSCH with the best fit available RBs (