NR SA UL MIMO
The purpose of this tutorial is to show you how to configure and test UL MIMO for NR SA. At this point, I don't have any commercial UE supporting UL MIMO. So the first test is with Amari Callbox and Amari UEsim and I will add the test with commercial UE as soon as I managed to get a commercial UE.
When you want to try UL MIMO test with your own UE, make it sure that your UE really support UL MIMO and the UE declare the support of UL MIMO in UE capability Information as shown in Precondition section.
Even though the configuration for UL MIMO in Amarisoft gNB is designed to be pretty simple, you need to have detailed understandings on 3GPP lower layer specification if you want to configure the test condition exactly as you intended. The specification you need through understanding for this test are summarized as follows :
- Precoding Matrix : 38.211 - Table 6.3.1.5-1 ~ Table 6.3.1.5-7
- Precoding and number of layers : 38.212 - Table 7.3.1.1.2-2 ~ Table 7.3.1.1.2-5
- Antenna Port : 38.212 - Table 7.3.1.1.2-6 ~ Table 7.3.1.1.2-23
Table of Contents
Introduction
Uplink Multiple Input Multiple Output (UL MIMO) is a fundamental technology in 5G New Radio (NR) Standalone (SA) networks, designed to significantly enhance uplink data throughput, spectral efficiency, and overall network capacity. UL MIMO leverages multiple transmitting antennas at the User Equipment (UE) and multiple receiving antennas at the gNodeB (gNB) to enable spatial multiplexing, allowing simultaneous transmission of multiple data streams within the same frequency resources. This advanced radio feature is governed by the 3GPP specifications, particularly in TS 38.211 and TS 38.212, which define the physical layer procedures, precoding matrices, layer mapping, and antenna port configurations essential for efficient MIMO operation. The adoption of UL MIMO in NR SA architectures not only improves the user experience by supporting higher throughput for uplink-heavy applications but also plays a critical role in supporting emerging use cases such as enhanced mobile broadband (eMBB), ultra-reliable low-latency communications (URLLC), and massive machine-type communications (mMTC). Understanding and correctly configuring UL MIMO requires an in-depth comprehension of 3GPP lower layer specifications, especially regarding precoding, layer management, and antenna port mapping, as these parameters directly impact the effectiveness of MIMO transmissions. In the context of this tutorial, you will learn how to configure and test UL MIMO using the Amarisoft gNB and UEsim, providing hands-on experience that is directly applicable to commercial deployments as more UEs with UL MIMO capability become available. This forms a crucial competency for network engineers and testers working in the rapidly evolving 5G ecosystem.
-
Context and Background
- UL MIMO is a key enabler for maximizing uplink performance in 5G NR SA deployments, allowing UEs and gNBs to transmit and receive multiple data streams simultaneously.
- The technology builds on foundational concepts from previous generations but introduces more flexible and scalable mechanisms defined by 3GPP Release 15 and onward.
- Amarisoft’s gNB and UEsim provide a configurable and controlled environment for validating UL MIMO features before testing with commercial UEs.
-
Relevance and Importance of Tutorial Topic
- With the increasing demand for uplink bandwidth and low latency in applications such as live video streaming, IoT, and industrial automation, mastering UL MIMO configuration is essential for network performance optimization.
- Understanding the intricacies of UL MIMO helps operators and engineers to fine-tune network parameters, ensuring robust and efficient 5G deployments.
-
Learning Outcomes
- Gain practical knowledge on how to configure and test UL MIMO in a simulated 5G NR SA environment using Amarisoft tools.
- Develop the ability to verify UE capability information and ensure device compatibility with UL MIMO features.
- Achieve a deeper understanding of relevant 3GPP lower layer specifications related to precoding, layer mapping, and antenna configuration for UL MIMO.
-
Prerequisite Knowledge and Skills
- Familiarity with 5G NR architecture and radio interface concepts.
- Basic understanding of MIMO principles and spatial multiplexing.
- Experience with Amarisoft gNB and UEsim tools, including configuration and operation.
- Ability to interpret and navigate 3GPP technical specifications, particularly TS 38.211 and TS 38.212.
Summary of the Tutorial
This tutorial demonstrates the configuration and validation of Uplink (UL) SISO and MIMO (2x2 and 4x4) transmission using the Amarisoft gNB and UEsim. The following summarizes the test procedures, steps, and methodologies used for each test case as described in the tutorial content.
-
Preconditions
- Ensure the Device Under Test (DUT) supports UL MIMO by verifying support for relevant features, including the maximum number of MIMO layers, SRS resources, and modulation order in the UE capability information.
-
Key Configuration Parameters
- Set srs_resource.n_ports to match the number of UL antennas.
- Configure pusch.max_rank and pusch.n_layer according to the UL antenna count.
-
Test 1: Reference Test - UL SISO
- Configure the gNB using gnb-sa-ulsiso.cfg:
- Set N_ANTENNA_UL to 1 for SISO.
- Enable SRS by setting USE_SRS to 1.
- Optionally, force UL PHY/MAC to schedule every possible UL slot with fixed MCS for throughput comparison.
- Configure n_ports in srs_resource to 1.
- Set max_rank and n_layer in pusch to 1.
- Optionally extend inactivity_timer to allow checking PHY throughput without generating IP throughput.
- Configure the UEsim using ue-nr-sa-ulsiso.cfg:
- Set N_ANTENNA_UL and N_ANTENNA_DL to match the gNB configuration (both set to 1).
- Test Execution:
- Verify cell configuration, especially UL configuration, using cell phy and rf_info commands.
- Power on the UE in UEsim and check for successful attach and throughput. Use this as a reference throughput for MIMO cases.
- Log Analysis:
- Check that maxRank in pusch-Config is 1.
- Verify nrofSRS-Ports is set to 1.
- Check PHY layer DCI and PUSCH logs for single layer (SISO) operation.
- Configure the gNB using gnb-sa-ulsiso.cfg:
-
Test 2: UL MIMO - 2x2
- Configure the gNB using gnb-sa-ulmimo.cfg:
- Set N_ANTENNA_UL to 2 for 2x2 MIMO.
- Enable SRS (USE_SRS = 1).
- Optionally, schedule all UL slots with fixed MCS.
- Set n_ports in srs_resource to 2.
- Set max_rank and n_layer in pusch to 2.
- Optionally extend inactivity_timer.
- Configure the UEsim using ue-nr-sa-ulmimo.cfg:
- Set N_ANTENNA_UL and N_ANTENNA_DL to 2 to match the gNB configuration.
- Test Execution:
- Use cell phy and rf_info commands to confirm 2 RX channels and correct configuration.
- Power on the UE and confirm attach and throughput. Compare throughput with the SISO reference.
- Log Analysis:
- Check maxRank in pusch-Config is set to 2.
- Verify nrofSRS-Ports is 2.
- Review DCI and PUSCH logs to confirm 2-layer operation.
- Configure the gNB using gnb-sa-ulmimo.cfg:
-
Test 3: UL MIMO - 4x4
- Configure the gNB using gnb-sa-ulmimo-4x4.cfg:
- Set N_ANTENNA_UL to 4 for 4x4 MIMO.
- Enable SRS (USE_SRS = 1).
- Optionally, schedule all UL slots with fixed MCS.
- Set n_ports in srs_resource to 4.
- Set max_rank and n_layer in pusch to 4.
- Optionally extend inactivity_timer.
- Configure the UEsim using ue-nr-sa-ulmimo-4x4.cfg:
- Set N_ANTENNA_UL and N_ANTENNA_DL to 4 to match the gNB configuration.
- Test Execution:
- Use cell phy and rf_info commands to confirm 4 RX channels and correct configuration.
- Power on the UE and confirm attach and throughput. Compare throughput with the SISO reference.
- Log Analysis:
- Check maxRank in pusch-Config is set to 4.
- Verify nrofSRS-Ports is 4.
- Review DCI and PUSCH logs to confirm 4-layer operation.
- Configure the gNB using gnb-sa-ulmimo-4x4.cfg:
For all tests, it is emphasized that the number of SRS ports, max_rank, and n_layer parameters should correspond to the number of UL antennas used. The n_layer parameter is not mandatory for Amarisoft callbox UL MIMO operation as the default configuration follows the UE-reported CSI, but can be used if forced MIMO configuration is required.
Each test involves verifying the configuration on both the gNB and UEsim, powering on the UE, confirming successful attachment, and measuring throughput. The log analysis steps are focused on confirming that the intended MIMO configuration is correctly applied and reflected in both signaling and PHY layers.
Test Setup
Test setup for this tutorial is as shown below.

Preconditions
Before you try any test in this tutorial, make it sure that your UE (DUT) support UL MIMO. An easy way to check if the UE support UL MIMO or not is to check following IE in UE capability Information.
featureSetsUplinkPerCC {
{
supportedSubcarrierSpacingUL kHz30,
supportedBandwidthUL fr1: mhz20,
mimo-CB-PUSCH {
maxNumberMIMO-LayersCB-PUSCH twoLayersmaxNumberSRS-ResourcePerSet 1
},
supportedModulationOrderUL qam256
}
},
Key Configuration Parameters
Followings are important configuration parameters for this tutorial. You may click on the items for the descriptions from Amarisoft documents.
Test 1 : Reference Test - UL SISO
This test is not for UL MIMO, but I decided to perform this test as a reference (i.e, comparative purpose with the test result for MIMO case) before trying UL MIMO. It would be helpful to understand the concept of UL MIMO if you compare this reference with other test cases.
Configuration
I used the gnb-sa-ulsiso.cfg on gNB which is copied and modified from gnb-sa.cfg

In gnb-sa-ulsiso.cfg , the configuration is done as follows. I set UL to SISO for reference and enabled SRS as well. Set N_ANTENNA_UL to 1 to configure for SISO and USE_SRS to 1 to enable SRS.

It is not mandatory but I forced UL PHY/MAC to schedule every possible UL slots with fixed mcs to compare this reference with other test in terms of throughput.

One important thing to note is that number of srs port (n_ports) in srs_resource configuration is same as the number of MIMO antenna (N_ANTENNA_UL).

I also set max_rank and n_layer of pusch configuration to be same as the number of UL antenna. These configuration (max_rank and n_layer) will be reflected into RRC message. (

This is not mandatory either. I extended inactivity_timer for long enough to check phy throughput without generating IP throughput.

I used the ue-nr-sa-ulsiso.cfg on UEsim which is copied and modified from ue-nr-sa.cfg

In ue-nr-sa-ulsiso.cfg , the configuration is done as follows.
I set the number of ULand DL antenna of UEsim to be same as the number of UL and DL antenna of Callbox(gNB) by setting the value of N_ANTENNA_DL and N_ANTENNA_UL.


Perform the Test
Check if the cell is configured as intended. The important thing in this test is Uplink configuration. Check out the number of UL ANT and NL(number of layers) with cell phy command and check out RX channels and port with rf_info command.

Power on UE on UE sim if everything is configured as you intended.

Confirm that the UE completes the attach and check the throughput. It would be better to remember the UL throughput of this test as a reference.

Log Analysis
Now let's look into the log and see how the configuration is reflected in signaling message.
The first important thing to check is maxRank value in pusch-Config of RRC Setup. Since this test is SISO, it is set to 1.

Next to check is the number of srs port. You can confirm on it with nrofSRS-Ports of srs-ResourceToAddModList. In this test, it is set to port1 since it is SISO.

Lastly let's check about the operation at PHY layer.
First thing you need to check is the field antenna_ports in DCI 0_1. Interpretation of the value is a little bit complicated. Check out this note for the interpretation of this field.

Next thing to check is the number of layers for PUSCH. Number of layers for PUSCH is informed via nl field in PUSCH log. In this case, nl field is not printed in the log. It means the value of nl is 1 which indicates SISO.

Test 2 : UL MIMO - 2x2
This test is to show how to configure and validate UL 2x2 MIMO.
Configuration
I used the gnb-sa-ulmimo.cfg on gNB which is copied and modified from gnb-sa.cfg

In gnb-sa-ulmimo.cfg , the configuration is done as follows. I set UL to 2x2 MIMO for reference and enabled SRS as well. Set N_ANTENNA_UL to 2 to configure for SISO and USE_SRS to 1 to enable SRS.

It is not mandatory but I forced UL PHY/MAC to schedule every possible UL slots with fixed mcs to compare this reference with other test in terms of throughput.

One important thing to note is that number of srs port (n_ports) in srs_resource configuration is same as the number of MIMO antenna (N_ANTENNA_UL).

I also set max_rank and n_layer of pusch configuration to be same as the number of UL antenna. These configuration (max_rank and n_layer) will be reflected into RRC message. (

This is not mandatory either. I extended inactivity_timer for long enough to check phy throughput without generating IP throughput.

I used the ue-nr-sa-ulmimo.cfg on UEsim which is copied and modified from ue-nr-sa.cfg

In ue-nr-sa-ulmimo.cfg, the configuration is done as follows.
I set the number of ULand DL antenna of UEsim to be same as the number of UL and DL antenna of Callbox(gNB) by setting the value of N_ANTENNA_DL and N_ANTENNA_UL.


Perform the Test
Check if the cell is configured as intended.
Check if the cell is configured as intended. The important thing in this test is Uplink configuration. Check out the number of UL ANT and NL(number of layers) with cell phy command and check out RX channels and port with rf_info command. You see 2 RX channels are configured.

Power on UE on UE sim.

Confirm that the UE completes the attach and check the throughput. Confirm that the UE completes the attach and check the throughput. Compare the throughput with the reference throughput that you had with SISO.

Log Analysis
Now let's look into the log and see how the configuration is reflected in signaling message.
The first important thing to check is maxRank value in pusch-Config of RRC Setup. Since this test is 2x2 MIMO, it is set to 2.

Next to check is the number of srs port. You can confirm on it with nrofSRS-Ports of srs-ResourceToAddModList. In this test, it is set to port2 since it is 2x2 MIMO.

Lastly let's check about the operation at PHY layer.
First thing you need to check is the field antenna_ports and precoding_info in DCI 0_1 (

Next thing to check is the number of layers for PUSCH. Number of layers for PUSCH is informed via nl field in PUSCH log. In this case, nl field is set to 2 which indicates 2 layers. 2 layer indicates it is 2x2 or 2x4 or 2x8 MIMO etc.

Test 3 : UL MIMO - 4x4
This test is to show how to configure and validate UL 4x4 MIMO.
Configuration
I used the gnb-sa-ulmimo-4x4.cfg on gNB which is copied and modified from gnb-sa.cfg

In gnb-sa-ulmimo-4x4.cfg , the configuration is done as follows. I set UL to 4x4 MIMO for reference and enabled SRS as well. Set N_ANTENNA_UL to 4 to configure for SISO and USE_SRS to 1 to enable SRS.

It is not mandatory but I forced UL PHY/MAC to schedule every possible UL slots with fixed mcs to compare this reference with other test in terms of throughput.

One important thing to note is that number of srs port (n_ports) in srs_resource configuration is same as the number of MIMO antenna (N_ANTENNA_UL).

I also set max_rank and n_layer of pusch configuration to be same as the number of UL antenna. These configuration (max_rank and n_layer) will be reflected into RRC message. (

This is not mandatory either. I extended inactivity_timer for long enough to check phy throughput without generating IP throughput.

I used the ue-nr-sa-ulmimo-4x4.cfg on UEsim which is copied and modified from ue-nr-sa.cfg

In ue-nr-sa-ulmimo-4x4.cfg, the configuration is done as follows.
I set the number of ULand DL antenna of UEsim to be same as the number of UL and DL antenna of Callbox(gNB) by setting the value of N_ANTENNA_DL and N_ANTENNA_UL.


Perform the Test
Check if the cell is configured as intended.
Check if the cell is configured as intended. The important thing in this test is Uplink configuration. Check out the number of UL ANT and NL(number of layers) with cell phy command and check out RX channels and port with rf_info command. You see 4 RX channels are configured.


Power on UE on UE sim.

Confirm that the UE completes the attach and check the throughput. Confirm that the UE completes the attach and check the throughput. Confirm that the UE completes the attach and check the throughput. Compare the throughput with the reference throughput that you had with SISO.

Log Analysis
Now let's look into the log and see how the configuration is reflected in signaling message.
The first important thing to check is maxRank value in pusch-Config of RRC Setup. Since this test is 4x4 MIMO, it is set to 4

Next to check is the number of srs port. You can confirm on it with nrofSRS-Ports of srs-ResourceToAddModList. In this test, it is set to port4 since it is 4x4 MIMO.

Lastly let's check about the operation at PHY layer.
First thing you need to check is the field antenna_ports and precoding_info in DCI 0_1 (

Next thing to check is the number of layers for PUSCH. Number of layers for PUSCH is informed via nl field in PUSCH log. In this case, nl field is set to 4 which indicates 4 layers. 4 layer indicates it is 4x4 or 4x8 MIMO etc.

RRC / NAS Signaling
RrcSetup (SA)
: This is the RrcSetup message sent by gNB to configure NR SA. (
{
message c1: rrcSetup: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcSetup: {
radioBearerConfig {
...
},
masterCellGroup {
cellGroupId 0,
rlc-BearerToAddModList {
...
},
mac-CellGroupConfig {
...
},
physicalCellGroupConfig {
pdsch-HARQ-ACK-Codebook dynamic
},
spCellConfig {
spCellConfigDedicated {
initialDownlinkBWP {
pdcch-Config setup: {
...
},
pdsch-Config setup: {
...
}
},
firstActiveDownlinkBWP-Id 0,
uplinkConfig {
initialUplinkBWP {
pucch-Config setup: {
...
},
pusch-Config setup: {
txConfig codebook,
dmrs-UplinkForPUSCH-MappingTypeA setup: {
dmrs-AdditionalPosition pos1,
transformPrecodingDisabled {
}
},
pusch-PowerControl {
...
},
resourceAllocation resourceAllocationType1,
codebookSubset nonCoherent,
maxRank 4,
uci-OnPUSCH setup: {
...
}
},
srs-Config setup: {
...
},
firstActiveUplinkBWP-Id 0,
pusch-ServingCellConfig setup: {
}
},
pdcch-ServingCellConfig setup: {
},
pdsch-ServingCellConfig setup: {
...
},
csi-MeasConfig setup: {
...
},
tag-Id 0
}