TDD Pattern
The purpose of this tutorial is to show you how to select a specific TDD UL/DL pattern from the predefined configuration and add your own configuration. In this tutorial, I assume that you are familiar with basic operations of callbox and I would not explain the very basic operational procedure. I will just explain about the important configurations and how you can confirm on those configuration from the log.
Main point in this tutorial is about how to configure following configuration (i.e, tdd-UL-DL-configurationCommon parameters in 3GPP). The label in black is 3GPP terminology for each configuration and the one in red is corresponding Amarisoft parameters.

image source : tdd-UL-DL-configurationCommon in sharetechnote
Table of Contents
- TDD Pattern
- Introduction
- Summary of the Tutorial
- Test Setup
- Key Configuration Parameters
- Test 1 : Single Pattern from the default configuration
- Test 2 : Dual Pattern from the default configuration
- Test 3 : Define your own configuration
- Test 4 : High UL throughput with Default CSI Configuration
- Test 5 : High UL throughput with Modified CSI Configuration
- Test 6 : Low Latency (TDD Pattern = 1.0 ms)
- Test 7 : Max DL Allocation
- Test 8 : Single Pattern with Auto CSI Configuration
- Test 9 : High UL throughput with "Auto CSI without TRS"
- Test 10 : High UL throughput with "Auto CSI with TRS"
- Test 11 : Low Latency (TDD Pattern = 0.5 ms)
- RRC / NAS Signaling
- Common Errors
- Tips
Introduction
Time Division Duplexing (TDD) in 5G NR (New Radio) networks allows dynamic allocation of uplink (UL) and downlink (DL) resources within the same frequency band, enabling highly flexible spectrum utilization and supporting diverse service requirements. The configuration of TDD UL/DL patterns—formally defined as tdd-UL-DL-configurationCommon in 3GPP specifications—dictates the scheduling and alignment of radio frames, subframes, and slots for uplink and downlink transmissions. This architectural flexibility is crucial for adapting to varying traffic demands, minimizing latency, and maximizing throughput, especially in dense urban environments and for applications with asymmetric data requirements. At the implementation level, network elements such as gNBs (next-generation NodeBs or 5G base stations) must be meticulously configured to select from predefined TDD patterns or to introduce custom configurations in compliance with both 3GPP standards and vendor-specific parameters (such as those provided by Amarisoft). Understanding the interplay between 3GPP terminology and vendor configuration interfaces is essential for network engineers and system integrators to validate, optimize, and troubleshoot TDD configurations. This tutorial focuses on the practical aspects of selecting and customizing TDD UL/DL patterns using Amarisoft’s gNB software, highlighting the mapping between standardized configuration fields and proprietary parameters, and providing guidance on confirming correct operation via system logs. The knowledge and skills imparted here are vital for professionals tasked with deploying, tuning, and maintaining 5G NR TDD systems, ensuring robust and efficient network performance within the broader telecommunications ecosystem.
-
Context and Background
- TDD in 5G NR enables flexible, dynamic allocation of uplink and downlink resources within a shared frequency, optimizing spectrum usage and supporting diverse service profiles.
- The tdd-UL-DL-configurationCommon parameter, as defined by 3GPP, governs the timing and structure of UL/DL slots and symbols across the radio interface.
- Vendors such as Amarisoft implement these parameters through proprietary configuration fields, requiring a clear understanding of the mapping between standard and vendor-specific settings.
- Precise TDD configuration is necessary for meeting network performance targets and ensuring interoperability within multi-vendor and multi-operator environments.
-
Relevance and Importance of the Tutorial
- Configuring and customizing TDD patterns is a critical task in real-world 5G NR deployments, impacting latency, throughput, and user experience.
- This tutorial addresses the practical challenges network engineers face when selecting or modifying TDD patterns using Amarisoft’s gNB platform.
- It emphasizes the importance of validating configurations through logs and system feedback to ensure correctness and optimal operation.
-
What Learners Will Gain
- A clear understanding of TDD configuration concepts in 5G NR and their significance in network architecture.
- Practical knowledge of how to select from predefined TDD patterns or introduce custom configurations using Amarisoft’s interface.
- Ability to interpret and verify TDD configuration using system logs and mapping between 3GPP and vendor-specific parameters.
- Insights into best practices for maintaining compatibility with evolving software releases and scheduler behaviors.
-
Prerequisite Knowledge and Skills
- Familiarity with basic callbox operations and general 5G NR network concepts.
- Understanding of radio frame structure, slot configuration, and 3GPP specification terminology.
- Experience with Amarisoft gNB software or equivalent base station configuration tools is recommended.
- Basic ability to read and interpret system logs for verification and troubleshooting.
Summary of the Tutorial
This tutorial demonstrates various test procedures for configuring and verifying NR TDD UL/DL patterns on a 5G gNB using Amarisoft software. Each test shows different approaches to TDD pattern selection, custom configuration, and the integration of CSI-RS (Channel State Information - Reference Signal) settings, with a focus on both throughput and latency optimization.
- Test Setup
- The test setup involves a gNB connected to a UE, with SIM card as provided. For basic SIB1 verification, UE connection is not strictly necessary.
- Configuration changes can be made via the provided guides and sample files.
- Key Configuration Parameters
- Main parameters include tdd_ul_dl_config (with pattern1/pattern2, period, dl_slots, ul_slots, dl_symbols, ul_symbols) and resource_auto for CSI-RS automation.
- Test 1: Single Pattern from Default Configuration
- Select a predefined configuration file and set NR_TDD to TDD mode (1), NR_TDD_CONFIG to 1.
- Restart the LTE service, verify no errors on startup, and collect BCCH logs to inspect SIB1 for correct pattern reflection.
- Test 2: Dual Pattern from Default Configuration
- Set NR_TDD_CONFIG to 4 for a dual-pattern cycle (pattern1: 3ms, pattern2: 2ms).
- Follow the same procedure of restarting LTE service, checking for errors, and validating SIB1 for dual pattern application.
- Test 3: Define Your Own Configuration
- Create a custom NR_TDD_CONFIG section (e.g., set to 5), define new cycle length and slot/symbol allocations.
- Restart service, ensure error-free operation, and confirm SIB1 reflects the custom pattern.
- Note that custom configs may be impacted by additional parameters (e.g., CSI), requiring careful validation and reference to the common errors section.
- Test 4: High UL Throughput with Default CSI Configuration
- Similar to Test 3, but with a focus on maximizing UL slots and symbols (e.g., 6 UL slots, 10 UL symbols in a 5ms cycle).
- Validate that the configuration is 3GPP-compliant and check SIB1 for correct application.
- Test 5: High UL Throughput with Modified CSI Configuration
- Customizes CSI-RS positions to avoid collision with UL slots, adjusting first_symb and offset for each CSI-RS instance.
- Includes detailed parameter tuning for n_ports, frequency_domain_allocation, and cdm_type.
- Verify correct SIB1 reflection and note that the configuration may behave differently with various UEs.
- Test 6: Low Latency (TDD Pattern = 1.0 ms)
- Utilizes a default low-latency configuration with a 1 ms cycle (2 slots), minimal UL/DL slots, and no TRS CSI-RS.
- Disables SRS, minimizes k_min for faster scheduling, aligns PRACH and UL symbols, and places CSI-RS to avoid SSB overlap.
- Ensures all settings are valid for low-latency and checks SIB1 for the correct pattern.
- Test 7: Max DL Allocation
- Configures maximum allowed DL resources in a 2.5 ms cycle, with minimal UL allocation.
- Uses pucch0 for simplified resource allocation and removes extra DMRS symbols for short UL slots.
- Validate by log inspection and SIB1 check.
- Test 8: Single Pattern with Auto CSI Configuration
- Enables resource_auto for automatic CSI-RS configuration matching the selected TDD pattern.
- Uses a default TDD pattern and verifies that the software automatically configures compatible CSI-RS resources.
- Test 9: High UL Throughput with "Auto CSI without TRS"
- Demonstrates disabling TRS transmission (trs_presence: false) when auto CSI configuration leads to TRS setup errors due to insufficient DL slots.
- Validates the pattern in SIB1 and ensures error-free operation.
- Test 10: High UL Throughput with "Auto CSI with TRS"
- Shows how to enable TRS even in slots used for SSB and SIB1 by setting exclude_slot_ssb and exclude_slot_sib1 to false.
- Ensures two consecutive slots for TRS in FR1 are available and validates the configuration by checking SIB1.
- Test 11: Low Latency (TDD Pattern = 0.5 ms)
- Uses a 0.5 ms cycle (partial slots for DL and UL), disables SRS, minimizes k_min, and aligns PRACH for low-latency operations.
- Carefully positions CSI-RS to avoid SSB overlap and configures PUSCH to use all available UL symbols.
- Checks SIB1 for proper pattern application and validates with different UEs.
General Methodology Across Tests:
- Select or modify a configuration file appropriate for the test objective.
- Set NR_TDD to TDD mode and select the appropriate NR_TDD_CONFIG index.
- Restart LTE services, monitor for errors, and adjust configurations as necessary to resolve issues.
- Collect logs (typically via BCCH) and inspect SIB1 to verify that the TDD pattern and relevant parameters are reflected as intended.
- When using custom or advanced configurations, ensure that CSI-RS and other signaling resources do not conflict with the chosen TDD pattern.
- Refer to the Common Errors section for troubleshooting, especially regarding CSI-RS and UL slot collisions. Adjust CSI-RS positions or disable TRS as needed.
- For low latency or maximum throughput, follow specific guidelines (e.g., packing DL/UL symbols, careful PRACH and PUSCH allocation, minimizing k_min).
Additional Tips
- For low latency, reduce TDD periodicity and optimize PRACH and PUSCH allocation according to available UL symbols.
- When using special slots, configure pusch.partial_slots to enable PUSCH scheduling in those slots.
- Always validate new configurations for 3GPP compliance and operational stability.
Test Setup
Test setup for this tutorial is as shown below. (
- 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.
- tdd_ul_dl_config : In this link, you can get the descriptions for all the parameters listed below
- ref_subcarrier_spacing
- pattern1
- period
- dl_slots
- ul_slots
- dl_symbols
- ul_symbols
- pattern2
- period
- dl_slots
- ul_slots
- dl_symbols
- ul_symbols
- resource_auto : In this link, you can get the descriptions for all the parameters listed below
- trs_presence
- exclude_slot_ssb
- exclude_slot_sib1
Test 1 : Single Pattern from the default configuration
This is an example of a very simple and standard TDD pattern that is made up of single pattern. Around 70% allocated for downlink and around 20% allocated for uplink and a little bit less than 10% is configured for flexible slots (special slots).
Configuration
I used the configuration gnb-sa-tdd-pattern.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 1 which is one of default sample configuration provided by Amarisoft sample configuration.

For example, if you select TDD_CONFIG == 1 as in this test, the pattern as shown below is applied. In this configuration, the cycle length is 5ms which is 10 slots in case of Subcarrier spacing 30Khz. Out of the 10 slots, 7 slots and 2 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 2 slots and 2 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively.

Following is the simplified configuration.
|
tdd_ul_dl_config: { pattern1: { period: 5, dl_slots: 7, dl_symbols: 2, ul_slots: 2, ul_symbols: 2 } } |
Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1.
See if your configuration is properly relected into SIB1 as shown below. Important parameters are dl-UL-TransmissionPeriodicity = ms5, which means the TDD pattern repeats every 5 ms, nrofDownlinkSlots = 7, which means 7 slots are configured for downlink, nrofDownlinkSymbols = 2, which means 2 additional OFDM symbols are downlink in the flexible boundary area, nrofUplinkSlots = 2, which means 2 slots are configured for uplink, and nrofUplinkSymbols = 2, which means 2 additional OFDM symbols are uplink in the boundary region. This matches the configuration style you showed earlier. So this decode is the direct confirmation that the TDD setting was not just written in the config file, but was actually encoded into the broadcast RRC message and transmitted by the cell.

Test 2 : Dual Pattern from the default configuration
This is a little bit complicated configuration than the case of previous test. It is made up of two patterns. The first pattern takes up 60 % of the overall cycle and the second pattern takes up 40% of the overall cycle.
Configuration
I used the configuration gnb-sa-tdd-pattern.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 4 which is one of default sample configuration provided by Amarisoft sample configuration.

For example, if you select TDD_CONFIG == 4 as in this test, the pattern as shown below is applied.
This is an NR TDD UL/DL configuration with two repeating patterns. It defines how the radio frame is split between downlink and uplink over time.
For pattern1, the repetition period is 3 ms. In each repetition, gNB uses 3 full slots for downlink, then 6 additional downlink symbols, then 4 uplink symbols, and 2 full slots for uplink. This means pattern1 is a mixed DL/UL pattern where both downlink and uplink exist in the same period, with symbol-level switching in the middle. This type of pattern is used when you want both DL and UL opportunities within a short time window.
For pattern2, the repetition period is 2 ms. In each repetition, gNB uses 4 full slots for downlink and there are no additional downlink symbols, no uplink symbols, and no uplink slots. This means pattern2 is a pure downlink-only region. It is typically used when the system wants to allocate extra downlink capacity without any uplink transmission in that part of the cycle.
Simply put, pattern1 is a mixed traffic pattern. pattern2 is a downlink-heavy extension. Together they create a cycle where the cell serves both DL and UL, but gives stronger emphasis to downlink traffic..

Following is the simplified configuration.
|
tdd_ul_dl_config: { pattern1: { period: 3, /* in ms */ dl_slots: 3, dl_symbols: 6, ul_symbols: 4, ul_slots: 2, }, pattern2: { period: 2, /* in ms */ dl_slots: 4, dl_symbols: 0, ul_symbols: 0, ul_slots: 0, }, } |
Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below.
Important Parameters are referenceSubcarrierSpacing = kHz30, which tells the UE that the TDD slot pattern is defined based on 30 kHz SCS, pattern1 which is the main mixed DL/UL pattern, and pattern2 which is the second pattern appended to the TDD cycle.
For pattern1, gNB sends dl-UL-TransmissionPeriodicity = ms10, nrofDownlinkSlots = 3, nrofDownlinkSymbols = 6, nrofUplinkSlots = 2, and nrofUplinkSymbols = 4. This means the first pattern repeats every 10 ms and contains 3 full DL slots, then 6 extra DL symbols, then 4 UL symbols, and then 2 full UL slots. This is a mixed pattern with symbol-level switching between DL and UL.
For pattern2, gNB sends dl-UL-TransmissionPeriodicity-v1530 = ms3, dl-UL-TransmissionPeriodicity = ms2, nrofDownlinkSlots = 4, nrofDownlinkSymbols = 0, nrofUplinkSlots = 0, and nrofUplinkSymbols = 0. This means the second pattern is a pure downlink-only section with 4 DL slots and no uplink part. In practical terms, this adds an extra DL-heavy region after the mixed part of pattern1.
So this highlighted decode is the direct confirmation that your configured pattern1 and pattern2 were properly encoded into the RRC system information and transmitted on the air.

Test 3 : Define your own configuration
This test is just to show you how to define your own TDD DL/UL ConfigCommon. There are roughly two different ways to do it.
i) Just change values of the configuration that are defined in the basic config file (e.g, gnb-sa.cfg)
ii) Create you own ‘#elif NR_TDD_CONFIG == X’ section
I am using the method ii) in this section
Configuration
I used the configuration gnb-sa-tdd-pattern.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 5 which is not in the list of default sample configuration provided by Amarisoft sample configuration.
(

Define your own configuration as follows (this is not the one in the default configuration). In this configuration, the cycle length is 2.5ms which is 5 slots in case of Subcarrier spacing 30Khz. Out of the 5 slots, 3 slots are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 1 slots and 10 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively.

Refer to [Common Errors] section for some possible errors you may see when you configure this parametes on your own.
Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below.
See if your configuration is properly relected into SIB1 as shown below. For pattern1, gNB sends dl-UL-TransmissionPeriodicity = ms2p5 to define a 2.5 ms repetition period, nrofDownlinkSlots = 3 to allocate 3 full DL slots, nrofDownlinkSymbols = 0 to indicate there is no additional DL symbol portion in a mixed slot, nrofUplinkSlots = 1 to allocate 1 full UL slot, and nrofUplinkSymbols = 10 to allocate 10 UL symbols in the mixed slot. This means the pattern is DL-to-UL switching within the same period, with 3 full downlink slots followed by a mixed boundary that is mostly uplink, and then 1 full uplink slot.

Test 4 : High UL throughput with Default CSI Configuration
This test is just to show you how to define your own TDD DL/UL ConfigCommon. There are roughly two different ways to do it.
i) Just change values of the configuration that are defined in the basic config file (e.g, gnb-sa.cfg)
ii) Create you own ‘#elif NR_TDD_CONFIG == X’ section
I am using the method ii) in this section
Configuration
I used the configuration gnb-sa-ul-highTp-defCSI.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 5 which is not in the list of default sample configuration provided by Amarisoft sample configuration.
(

Define your own configuration as follows (this is not the one in the default configuration). In this configuration, the cycle length is 5ms which is 10 slots in case of Subcarrier spacing 30Khz. Out of the 10 slots, 3 slots and 2 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 6 slots and 10 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively. I configured the uplink portion as large as possible without requiring additional CSI-RS-related changes in gnb-sa.cfg. In gnb-sa.cfg, slot 0 is already reserved for downlink transmission for SSB. In addition, CSI-RS is configured in slot 1 and slot 2. Therefore, at least 3 downlink slots are needed in total. This is why the TDD pattern is configured with dl_slots = 3.

Refer to [Common Errors] section for some possible errors you may see when you configure this parametes on your own.
Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below. (NOTE : I have tried this configuration with a commercial UE (OnePLUS 8T) and it successfully attached to gNB and Internet Speedtest was running OK.
See if your configuration is properly relected into SIB1 as shown below. Important parameters are referenceSubcarrierSpacing = kHz30, which tells UE that the TDD pattern is based on 30 kHz SCS, dl-UL-TransmissionPeriodicity = ms5, which tells UE that the pattern repeats every 5 ms, nrofDownlinkSlots = 3, which means 3 full slots are allocated for downlink, nrofDownlinkSymbols = 2, which means 2 additional OFDM symbols are allocated for downlink in the switching slot, nrofUplinkSlots = 6, which means 6 full slots are allocated for uplink, and nrofUplinkSymbols = 10, which means 10 OFDM symbols are allocated for uplink in the switching slot.

Test 5 : High UL throughput with Modified CSI Configuration
This test is just to show you how to define your own TDD DL/UL ConfigCommon. There are roughly two different ways to do it.
i) Just change values of the configuration that are defined in the basic config file (e.g, gnb-sa.cfg)
ii) Create you own ‘#elif NR_TDD_CONFIG == X’ section
I am using the method ii) in this section
Configuration
I used the configuration gnb-sa-ul-highTp-modCSI.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 5 which is not in the list of default sample configuration provided by Amarisoft sample configuration.
(

Define your own configuration as follows (this is not the one in the default configuration). In this configuration, the cycle length is 5ms which is 10 slots in case of Subcarrier spacing 30Khz. Out of the 10 slots, 1 slots and 10 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 8 slots and 2 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively.
In this example, I define another custom NR TDD pattern to maximize uplink resources. In the default gnb-sa.cfg sample scenario, slot 0 is used for SSB transmission and CSI-RS is configured in slot 1 and slot 2. Because of this, the default setup practically requires 3 downlink slots in total. To make more room for uplink, I modify the CSI-RS configuration so that CSI-RS is transmitted within the first 20 OFDM symbols without overlapping with SSB. With this change, the TDD pattern can be reconfigured with only 1 full downlink slot and 10 additional downlink symbols, while 8 full uplink slots and 2 uplink symbols are allocated for uplink. The pattern period is 5 ms, which corresponds to 10 slots at 30 kHz SCS. This configuration keeps the required downlink transmissions for synchronization and reference signaling, but shifts as much of the remaining time as possible to uplink.

Refer to [Common Errors] section for some possible errors you may see when you configure this parametes on your own.
I changed slot and symbol position of CSI-RS so that they are all positioned with 20 symbols.
The parameters to be noted in this example are as follows : (NOTE : the detailed meaning of each of these parameter in terms of 3GPP, check out this note)
In this example, the main point is to place several CSI-RS resources within a limited downlink region while avoiding collision with SSB and while also meeting the intended role of each CSI-RS resource. The parameter csi_rs_id = 0 is used for CSI reporting. The parameters csi_rs_id = 1, 2, 3, 4 are used for TRS. Therefore, the configuration purpose is different between ID 0 and ID 1 to 4, even though they are all defined under CSI-RS resources.
The parameters first_symb and offset are the most important timing parameters in this example. first_symb defines the OFDM symbol location within the slot where the CSI-RS starts. offset defines the slot-level time offset for the periodic transmission. These values are selected so that different CSI-RS resources do not overlap with each other, and also do not collide with SSB. For example, the TRS resources are distributed across different symbol locations such as 4, 8, and 12, and across different offsets such as 10 and 11. This spreads the resources in time so they can coexist within the limited DL region. The CSI-IM and ZP CSI-RS resources are also placed with symbol_location = 12 or first_symb = 12, with offset chosen to avoid collision with SSB.
Overall, this example shows how CSI-RS is divided into two groups. One group is for CSI reporting, mainly represented by csi_rs_id = 0. The other group is for TRS, represented by csi_rs_id = 1, 2, 3, 4. The configuration is built by carefully choosing mapping type, number of ports, symbol position, and offset so that all required CSI-RS transmissions fit into the available downlink symbols without colliding with SSB or with each other.
- frequency_domain_allocation, cdm_type : the configuration for csi_rs_id 0 is for CSI report and csi_rs_id 1,2,3,4 is to configure TRS.
- n_ports : this is set to be same as the number of DL Antenna for CSI report and set to 1 for TRS
- first_symb, offset : set these in such a way that does not overlap each other and set to meet TRS requirement if they are for TRS.





Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below. (
See if your configuration is properly relected into SIB1 as shown below. Important parameters are referenceSubcarrierSpacing = kHz30, which tells UE that the TDD pattern is based on 30 kHz SCS, dl-UL-TransmissionPeriodicity = ms5, which tells UE that the pattern repeats every 5 ms, nrofDownlinkSlots = 1, which means 1 full slot is allocated for downlink, nrofDownlinkSymbols = 10, which means 10 additional OFDM symbols are allocated for downlink in the switching slot, nrofUplinkSlots = 8, which means 8 full slots are allocated for uplink, and nrofUplinkSymbols = 2, which means 2 OFDM symbols are allocated for uplink in the switching slot. This means gNB configures a 5 ms TDD cycle made of 1 DL slot + 10 DL symbols + 8 UL slots + 2 UL symbols. This is a UL-heavy pattern. It keeps only the minimum DL region needed for SSB and CSI-RS related transmission, while moving most of the remaining symbols to uplink. This allows UE to determine exactly when to receive downlink and when to transmit uplink according to the broadcast NR TDD configuration.

Test 6 : Low Latency (TDD Pattern = 1.0 ms)
This is not a new configuration. It is default configuration in the installation package. I am just trying to show you the logics behind this low latency configuration. It would help you with applying the logic to create your own configuration when you need.
Some important points to pay attention to this configuration are as follows.
- Very short TDD pattern period : only two slots of period (1 ms, 1 subframe)
- 1 full slot for DL and 12 symbols for UL
- Removing CSI RS for TRS. (For FR1 TRS, we need at least two consecutive slots to configure TRS.. but we have only 1 slot for DL which cannot accommodate the TRS).
- CSI RS for CSI Report is positioned in slot 0 which is same slot as SSB. You need to position CSI-RS carefully so as NOT to overlap SSB symbols).
- Disable SRS. You may enable it if you really need it, but in that case you would need to decrease the number of symbols to PUSCH (lowering UL throughput) to reserve space for SRS.
- Reduce the value for k_min to reduce k1 and k2 min.
Configuration
I used the configuration gnb-sa-tdd-low-latency.cfg which is included in the installation package. (

In the configuration file, disable SRS.

This configuration creates a very short repeating TDD cycle. The whole pattern repeats every 2 slots, which is every 1 ms. This allows faster DL/UL turnaround for traffic, while still keeping a small transition gap between downlink and uplink.
In this example, the NR TDD pattern is configured with a 1 ms periodicity. With 30 kHz SCS, one slot is 0.5 ms, so a 1 ms cycle contains only 2 slots. Because one full slot is already assigned to downlink, the maximum remaining time for uplink is only one slot. However, instead of assigning the whole remaining slot to uplink, the configuration leaves a small switching gap between downlink and uplink.
The pattern is configured with dl_slots = 1 and dl_symbols = 0, which means the first full slot is used entirely for downlink. It is configured with ul_slots = 0 and ul_symbols = 12, which means there is no full uplink slot, but 12 OFDM symbols in the second slot are assigned for uplink. Since one NR slot normally has 14 OFDM symbols, this leaves 2 symbols unassigned. Those symbols act as a guard gap between DL and UL switching.

Reduce sr_period. This is to let UE not wait too long to get UL grant. If UL grant gets delayed, overall latency would get longer.

This configuration is meant to make the PRACH opportunity placement match the actual UL timing of the TDD pattern. This reduces the chance that a UE misses RACH because the configured RO falls on flexible symbols that some UE implementations may ignore. In this example, the PRACH configuration is selected so that the RO (RACH Occasion) falls only within the uplink symbols defined by the TDD pattern. In theory, a UE may also attempt PRACH on flexible symbols in a TDD UL/DL configuration. However, in practice, some UEs do not transmit RACH on those flexible symbols. Because of this, the PRACH configuration index is adjusted so that the allowed RACH occasions are aligned only with the symbols that are clearly configured as uplink.
The most important parameter here is prach_config_index = 128. This parameter determines the timing of PRACH opportunities. In this setup, it is chosen specifically so that the PRACH occasions appear only in the UL region of the configured TDD pattern. This avoids depending on UE behavior on flexible symbols and makes random access more reliable..

Reduce k_min value. This setting reduce the min value for k1 and k2 so that gNB can get UE response more quickly and grant ul more quicaly. This would required high CPU performance and you'd better check 't cpu' and real time condition maintains on your setup.
The main idea of this configuration is simple. gNB reduces k_min to shorten the minimum response timing between downlink scheduling, UE feedback, and uplink scheduling. This allows faster turnaround, but it also requires that the platform maintain sufficient CPU performance and real-time stability.
In this example, k_min is reduced to make the scheduling loop faster. This setting lowers the minimum timing for k1 and k2, so gNB can receive the UE response earlier and can issue uplink grants with less delay. As a result, the overall HARQ and UL scheduling reaction can become quicker.
This kind of setting is useful when you want more aggressive timing and lower latency. However, it also puts more burden on the processing chain. Since the scheduler, PHY processing, and real-time handling all need to react within a shorter time, this usually requires stronger CPU performance and stable real-time behavior in the system.

This configuration shows how to place the CSI-RS reporting resource at the beginning of each repetition period while keeping it clear of SSB. The main idea is simple. gNB sends CSI-RS for CSI report in the first slot of the period by using offset = 0, and places it at symbol 6 by using first_symb = 6 so that it does not overlap with SSB in symbols 2 to 5.
In this example, the CSI-RS for CSI reporting is placed at the first slot of each period, which is done by setting offset = 0. The main purpose is to make the CSI report resource appear at a predictable timing while avoiding collision with SSB. Since the SSB bitmap is 10000000, the active SSB occupies symbols 2, 3, 4, and 5. Therefore, the CSI-RS is placed at first_symb = 6, so it starts after the SSB region and does not overlap with those symbols.
The key parameters in this configuration are frequency_domain_allocation, bitmap, cdm_type, and n_ports. These parameters define the CSI-RS structure depending on the number of DL antennas. For 1 antenna, the example uses row2 with no_cdm. For 2, 4, and 8 antennas, it uses different combinations of frequency_domain_allocation, bitmap, and fd_cdm2 so that the CSI-RS matches the antenna-port configuration required for CSI reporting. In other words, n_ports is set to the same number as the DL antenna count because this resource is intended for CSI measurement.
The timing-related parameters are especially important here. period = 20 defines how often the CSI-RS repeats. offset = 0 places it in the first slot of that period. first_symb = 6 places it at symbol 6 within the slot, leaving room for SSB transmission in symbols 2 to 5. This is the main design point of this example. The CSI-RS is transmitted early in the period, but still late enough inside the slot to avoid SSB collision.
(
The parameters to be noted in this example are as follows : (NOTE : the detailed meaning of each of these parameter in terms of 3GPP, check out this note)
- frequency_domain_allocation, cdm_type : the configuration for csi_rs_id 0 is for CSI report and csi_rs_id 1,2,3,4 is to configure TRS.
- n_ports : this is set to be same as the number of DL Antenna for CSI report and set to 1 for TRS
- first_symb, offset : set these in such a way that does not overlap each other and set to meet TRS requirement if they are for TRS.


This configuration means this. gNB places CSI-IM and ZP CSI-RS in the first slot of the period by using offset = 0. gNB places them at symbol 8 so they do not overlap with SSB and do not collide with the previously configured NZP CSI-RS. This allows UE to perform interference measurement on the intended muted resources at a predictable timing.
In the same way, gNB places csi_im_resource and zp_csi_rs_resource in slot 0 of each period by setting offset = 0. The main purpose is to align them to the first slot of the repetition period, while making sure that their symbol location does not overlap with SSB or with nzp_csi_rs_resource.
For csi_im_resource, gNB sets period = 20 and offset = 0, so the resource appears in the first slot of every 20-slot period. symbol_location = 8 places the CSI-IM resource at symbol 8 within the slot. This is chosen so that it does not collide with the SSB symbols and also stays clear of the NZP CSI-RS resource that was already placed earlier in the slot. subcarrier_location = 8 defines the CSI-IM frequency-domain position. rb_start = 0 and l_crb = -1 mean the configuration starts from RB 0 and extends to the end of the bandwidth.
For zp_csi_rs_resource, gNB also sets period = 20 and offset = 0, so it is transmitted in the same first slot of each period. first_symb = 8 places the ZP CSI-RS at symbol 8, aligned with the CSI-IM resource. This is needed because ZP CSI-RS is used to mute the REs where CSI-IM is measured. Important parameters are frequency_domain_allocation = row4, bitmap = 100, n_ports = 4, and cdm_type = fd_cdm2, which define the ZP CSI-RS structure. density = 1, rb_start = 0, and l_crb = -1 define the RE density and full-bandwidth allocation.

This configuration means this. gNB allocates PUSCH so that it fills the UL symbol region defined by the TDD pattern. start_symb tells where the UL data starts, and n_symb tells how much of the slot is used for PUSCH. If the UL region changes because of TDD changes or SRS allocation, these values should also be updated so that PUSCH remains fully aligned with the available uplink symbols.
In this example, gNB configures PUSCH to occupy all the uplink symbols made available by the TDD pattern. The main idea is to match the PUSCH time-domain allocation to the UL region as tightly as possible, so uplink resources are fully utilized.
Important parameters are start_symb = 2 and n_symb = 12. This means PUSCH starts from symbol 2 of the UL slot and occupies 12 symbols. Since a normal slot has 14 OFDM symbols, this allocation fills symbols 2 through 13. In other words, the PUSCH region is designed to use almost the whole UL symbol area defined by the TDD configuration.
This is why the note says that if you reduce the number of UL symbols in the TDD pattern, or if you enable SRS, you need to adjust start_symb and n_symb accordingly. The PUSCH allocation cannot blindly stay the same. It has to be resized so that it fits only within the actual UL symbols left after considering guard time, SRS, or any other UL-related resource.

Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below. (
See if your configuration is properly relected into SIB1 as shown below. This means the cell is using a single TDD pattern. Important parameters are dl-UL-TransmissionPeriodicity = ms1, which corresponds to period = 1, nrofDownlinkSlots = 1, which corresponds to dl_slots = 1, nrofDownlinkSymbols = 0, which corresponds to dl_symbols = 0, nrofUplinkSlots = 0, which corresponds to ul_slots = 0, and nrofUplinkSymbols = 12, which corresponds to ul_symbols = 12. This means gNB broadcasts a TDD pattern of 1 full DL slot, no extra DL symbols, no full UL slot, and 12 UL symbols in the second slot. Since one slot has 14 symbols, the remaining 2 symbols are left as a gap between DL and UL. This matches the intended design where the total period is 1 ms at 30 kHz SCS, corresponding to 2 slots, and the UL part is intentionally set to less than one full slot to leave switching margin.

Test 7 : Max DL Allocation
This test is just to show you how to allocate time domain resources for DL as much as possible.
Configuration
I used the configuration gnb-sa-tdd-pattern-maxDL.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 5 which is not in the list of default sample configuration provided by Amarisoft sample configuration.
(

Define your own configuration as follows (this is not the one in the default configuration). In this configuration, the cycle length is 2.5ms which is 5 slots in case of Subcarrier spacing 30Khz. Out of the 5 slots, 4 slots and 6 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. Only 6 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively. Overall, this creates a strongly downlink-heavy pattern where about 89% of the available time-domain resources are allocated to downlink, which is suitable for scenarios where downlink traffic demand is much higher than uplink traffic.

Refer to [Common Errors] section for some possible errors you may see when you configure this parametes on your own.
This part shows how the PRACH configuration is adjusted to match the custom TDD UL/DL pattern. Since the TDD pattern leaves only the last 6 OFDM symbols for uplink in the mixed slot, the PRACH occasion also has to be placed within that limited uplink region. That is why prach_config_index: 136 is selected. The highlighted note explains that this index is chosen specifically because it allows the RACH occasion to exist only in the last 6 UL symbols defined by the TDD pattern. In other words, the PRACH resource is aligned with the actual uplink timing available in this special TDD configuration.

Use pucch0 instead of pucch1 because it would reduce the difficulties associated with resource allocation for PUCCH. pucch0 is used instead of pucch1 because it is much easier to fit into the limited uplink resources available in the configured pattern. Since the TDD configuration leaves only a small uplink region, resource allocation for a longer and more complex PUCCH format becomes difficult. By choosing pucch0, the configuration simplifies uplink control transmission and avoids many of the scheduling constraints that would arise with pucch1.

This PUSCH setting is tailored to the custom TDD pattern where only the last 6 OFDM symbols of the slot are available for uplink. Because of that, the configuration explicitly places PUSCH in that exact uplink region by setting start_symb: 8 and n_symb: 6. This means the PUSCH starts at symbol 8 of the slot and occupies the final 6 symbols, fully matching the UL portion defined by the TDD pattern. If the UL allocation in the TDD pattern changes, this PUSCH symbol allocation also needs to be updated to keep the uplink data transmission aligned with the available UL symbols.
The configuration uses mapping_type: "typeB", which is suitable for transmissions that start later in the slot rather than from the first symbol. That makes it a natural fit for this case, because the uplink region exists only at the end of the slot instead of spanning the full slot. In other words, this mapping allows the PUSCH to be placed cleanly into the short UL section created by the mixed-slot TDD design.
The parameter dmrs_add_pos: 0 shows that no additional DMRS symbols are inserted. This is done intentionally to reduce overhead. Since the PUSCH length here is only 6 symbols, removing the extra DMRS can be acceptable because the transmission is short and the channel variation over such a small symbol duration is usually manageable. As a result, more of the limited uplink symbols can be used for actual data instead of reference signals. However, the note also points out an important limitation: if PUSCH becomes longer, such as occupying a full slot, removing additional DMRS is usually not recommended because it can weaken channel tracking and increase the chance of PUSCH BLER.

Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below. (
This log shows the verification step after defining the custom TDD configuration in the gNB configuration file. The key point is that changing the local config file alone is not enough. You also need to confirm that the same setting is actually reflected in the RRC signaling sent by the base station. In this example, the Amarisoft Web GUI is opened on the RRC log view, and repeated SIB1 messages are shown in the message list. On the right side, the decoded SIB1 contents include tdd-UL-DL-ConfigurationCommon, which is the field that delivers the TDD pattern to the UE.
The highlighted red box shows that the configured pattern is indeed present in the transmitted RRC message. It indicates dl-UL-TransmissionPeriodicity ms2p5, which matches the intended 2.5 ms TDD cycle. It also shows nrofDownlinkSlots 4, nrofDownlinkSymbols 6, nrofUplinkSlots 0, and nrofUplinkSymbols 6. This confirms that the exact custom pattern defined in the config file has been encoded into SIB1 and is being broadcast over the air.
So this is used as a double-check point. It verifies that the TDD parameters were not only written in the configuration file, but were also successfully applied by the gNB software and included in the RRC system information. This is important because the UE follows the over-the-air RRC signaling, not the raw local config file. If the values shown in SIB1 do not match the intended setup, the UE behavior will follow the broadcast configuration rather than the engineer's expectation.

Test 8 : Single Pattern with Auto CSI Configuration
From 2022-06-17, Auto CSI configuration is supported to simplify the CSI configuration. With this feature, you may just change tdd pattern without modifying CSI configuration manually. gNB software configures CSI automatically to be compatible with the tdd configuration you configured. (For further details of Auto CSI configuration itself, please refer to Reference Configuration : Auto CSI Configuration )
Configuration
I used the configuration gnb-sa-autoCSI.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 2 which is one of default sample configuration provided by Amarisoft sample configuration.

For example, if you select TDD_CONFIG == 2 as in this test, the pattern as shown below is applied. In this configuration, the cycle length is 5ms which is 10 slots in case of Subcarrier spacing 30Khz. Out of the 10 slots, 7 slots and 6 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 2 slots and 4 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively.

In auto CSI configuration, the whole csi-rs configuration is as simple as shown below. This example shows how simple the CSI-RS setup becomes when auto configuration is used. Instead of manually defining every CSI-RS resource, resource set, mapping, and reporting detail, the configuration only provides a few high-level inputs and lets the gNB software generate the rest automatically. In this case, under resource_auto, only nzp_csi_rs_period: 80 is specified, which tells the gNB the transmission periodicity for NZP CSI-RS. In FR2, trs_presence: false is also set, meaning TRS is not included. The reporting side is also kept very simple. Inside csi_report_config, the example defines only one periodic report configuration with report_config_type: "periodic" and period: 80. This means the UE is instructed to send CSI reports periodically with the same interval. All the lower-level CSI-RS details that are not explicitly written here are automatically determined by the gNB software.

Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below.
See if your configuration is properly relected into SIB1 as shown below. This shows dl-UL-TransmissionPeriodicity ms5, which means the TDD cycle length is 5 ms. It also shows nrofDownlinkSlots 7, nrofDownlinkSymbols 6, nrofUplinkSlots 2, and nrofUplinkSymbols 4. This tells us that the gNB is advertising a pattern with 7 full downlink slots, 6 additional downlink symbols in the mixed slot, 2 full uplink slots, and 4 uplink symbols in the mixed slot. In other words, the custom UL/DL split is not just written in the local configuration. It is actually encoded into the RRC system information and sent over the air.

Test 9 : High UL throughput with "Auto CSI without TRS"
From 2022-06-17, Auto CSI configuration is supported to simplify the CSI configuration. With this feature, you may just change tdd pattern without modifying CSI configuration manually. gNB software configures CSI automatically to be compatible with the tdd configuration you configured. (For further details of Auto CSI configuration itself, please refer to Reference Configuration : Auto CSI Configuration )
In many of the typical TDD pattern, the default auto csi configuration would properly configure the CSI RS, but sometimes you may need to add some additional configurations to avoid any possible limitation (for example, in case when the number of DL slots is not enough to configure the necessary TRS).
This test is an example where you need to add some additional configuration to the default auto csi configuration. If you apply the tdd pattern in this example with the default auto csi configuration, you would get an error about TRS configuration setup. To remove the error, I disabled TRS transmission.
Configuration
I used the configuration gnb-sa-ul-highTp-autoCSI-noTRS.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 5 which is not in the list of default sample configuration provided by Amarisoft sample configuration.
(

For example, if you select TDD_CONFIG == 5 as in this test, the pattern as shown below is applied. In this configuration, the cycle length is 5ms which is 10 slots in case of Subcarrier spacing 30Khz. Out of the 10 slots, 1 slots and 10 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 8 slots and 2 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively.

In this test, trs_presence: false is set to explicitly disable TRS-related CSI-RS configuration. That means the gNB will not configure CSI-RS resources for tracking reference signals. As a result, the system avoids transmitting TRS and also avoids any configuration or processing issues that may be tied to TRS handling. This can be useful when the main goal is to simplify the CSI-RS setup or to isolate a problem during testing. By turning TRS off, you can focus only on the essential CSI-RS behavior without involving additional tracking-related signaling. In other words, this setting removes one possible source of errors or unexpected behavior, so it is often used as a practical troubleshooting step when investigating CSI or measurement-related problems.

Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below.
We can see that the broadcast TDD pattern uses dl-UL-TransmissionPeriodicity ms5, nrofDownlinkSlots 1, nrofDownlinkSymbols 10, nrofUplinkSlots 0, and nrofUplinkSymbols 2. This means the cell is operating with a 5 ms TDD cycle in which one full slot and ten additional symbols are assigned to downlink, while the uplink part is reduced to only two symbols in the mixed slot and there is no full uplink slot. So this screen confirms that the gNB is really transmitting the intended UL/DL pattern over the air.

Test 10 : High UL throughput with "Auto CSI with TRS"
From 2022-06-17, Auto CSI configuration is supported to simplify the CSI configuration. With this feature, you may just change tdd pattern without modifying CSI configuration manually. gNB software configures CSI automatically to be compatible with the tdd configuration you configured. (For further details of Auto CSI configuration itself, please refer to Reference Configuration : Auto CSI Configuration )
In many of the typical TDD pattern, the default auto csi configuration would properly configure the CSI RS, but sometimes you may need to add some additional configurations to avoid any possible limitation (for example, in case when the number of DL slots is not enough to configure the necessary TRS).
This test is an example where you need to add some additional configuration to the default auto csi configuration. If you apply the tdd pattern in this example with the default auto csi configuration, you would get an error about TRS configuration setup. To remove the error, I added the additional configurations.
Configuration
I used the configuration gnb-sa-ul-highTp-autoCSI-TRSonSSB.cfg which is copied from gnb-sa.cfg and modified for this tutorial.

In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. In the configuration file, you can select any specific tdd pattern with the parameter NR_TDD_CONFIG. To apply TDD configuration, you first need to configure the duplex mode (NR_TDD) to 1 (TDD). And then I set NR_TDD_CONFIG to 5 which is not in the list of default sample configuration provided by Amarisoft sample configuration.
(

For example, if you select TDD_CONFIG == 5 as in this test, the pattern as shown below is applied. In this configuration, the cycle length is 5ms which is 10 slots in case of Subcarrier spacing 30Khz. Out of the 10 slots, 1 slots and 10 OFDM symbols are allocated for downlink by the parameter dl_slots and dl_symbols respectively. 8 slots and 2 OFDM symbols are allocated for uplink by the parameter ul_slots and ul_symbols respectively.

In this test, I set the following two parameters which enable trs transmission even on ssb and sib1 slots to secure the two consecutive slots which is required for TRS transmission in FR1. The configuration is adjusted so that CSI-RS can still be transmitted even in slots that normally contain SSB or SIB1. This is done by setting exclude_slot_sib1: false and exclude_slot_ssb: false. Normally, those slots may be excluded from CSI-RS scheduling to avoid overlap with broadcast signals. Here, that restriction is removed on purpose.
The reason for doing this is to secure at least two consecutive slots for TRS transmission in FR1. TRS typically needs a continuous slot arrangement, so if SSB or SIB1 slots are excluded, it may become difficult or impossible for the gNB to find a valid pair of consecutive slots for TRS. By allowing CSI-RS scheduling even in SIB1 and SSB slots, the scheduler has more flexibility and can create the continuous transmission opportunity required for TRS.
So the main idea of this setup is not just to simplify the configuration, but to intentionally relax slot exclusion rules so that TRS can be configured successfully in FR1. The rest of the CSI-RS configuration remains simple, with nzp_csi_rs_period: 80 defining the periodicity and a periodic CSI report configured with period: 80. But these two additional parameters are the key part of the test, because they make TRS transmission feasible by preventing SIB1 and SSB slots from being automatically blocked out.

Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below.
This log shows the verification step after modifying the CSI-RS auto configuration to allow scheduling even in SIB1 and SSB related slots. The important point here is that, after changing parameters such as exclude_slot_sib1: false and exclude_slot_ssb: false, you should still confirm that the overall running cell configuration is correctly applied in the live RRC signaling. In the Amarisoft Web GUI, the selected message is SIB1, and the decoded contents on the right side show the tdd-UL-DL-ConfigurationCommon field highlighted for inspection.
From the decoded SIB1, we can see that the gNB is broadcasting dl-UL-TransmissionPeriodicity ms5, nrofDownlinkSlots 1, nrofDownlinkSymbols 10, nrofUplinkSlots 0, and nrofUplinkSymbols 2. This means the active TDD pattern is a 5 ms cycle with one full downlink slot, ten additional downlink symbols, no full uplink slot, and only two uplink symbols in the mixed slot. So this screen confirms that the serving cell is operating with the intended downlink-heavy TDD structure while the CSI-RS related slot-exclusion behavior has been relaxed in the local configuration.
The reason this check is important is that TRS operation in FR1 depends not only on the CSI-RS parameters themselves, but also on whether the actual running cell pattern provides a valid scheduling opportunity. The UE will follow what is broadcast in SIB1, not what is written in the config file. Therefore, this log view serves as a final sanity check that the gNB is using the expected TDD framework while you test whether enabling CSI-RS in SIB1 and SSB slots can secure the consecutive slots needed for TRS transmission.

Test 11 : Low Latency (TDD Pattern = 0.5 ms)
This is not a new configuration. It is default configuration in the installation package. I am just trying to show you the logics behind this low latency configuration. It would help you with applying the logic to create your own configuration when you need.
Some important points to pay attention to this configuration are as follows.
- Very short TDD pattern period : only two slots of period (0.5 ms, half subframe/one slot)
- partial slot for DL and partial slot for UL
- Removing CSI RS for TRS. (For FR1 TRS, we need at least two consecutive slots to configure TRS.. but we have only 1 slot for DL which cannot accommodate the TRS).
- CSI RS for CSI Report is positioned in slot 0 which is same slot as SSB. You need to position CSI-RS carefully so as NOT to overlap SSB symbols).
- Disable SRS. You may enable it if you really need it, but in that case you would need to decrease the number of symbols to PUSCH (lowering UL throughput) to reserve space for SRS.
- Reduce the value for k_min to reduce k1 and k2 min.
Configuration
I used the configuration gnb-sa-tdd-low-latency_0_5.cfg which is copied and modified from gnb-sa-tdd-low-latency.cfg

In the configuration file, disable SRS.

This configuration shows an extremely short TDD cycle designed for fast switching between downlink and uplink. The period: 0.5 means the whole UL/DL pattern repeats every 0.5 ms. With 30 kHz subcarrier spacing, that corresponds to one slot. In other words, the gNB reuses the same TDD pattern every slot, which allows very fast traffic turnaround and can help reduce waiting time for uplink or downlink transmission opportunities.
Because the entire cycle is only one slot long, there is no room for separate full downlink and full uplink slots. Instead, the single slot is split into a mixed structure. In this configuration, dl_slots: 0 and ul_slots: 0 mean there are no complete slots dedicated entirely to downlink or uplink. Instead, dl_symbols: 9 assigns the first 9 OFDM symbols of the slot to downlink, and ul_symbols: 4 assigns the last 4 OFDM symbols to uplink. So the slot is divided into a downlink part and an uplink part within the same slot.
This kind of configuration is useful when you want quick response time rather than long continuous downlink or uplink bursts. Since the pattern repeats every slot, the UE does not need to wait long before the transmission direction changes. That makes it suitable for traffic patterns requiring frequent UL/DL alternation. At the same time, because both directions share the same slot, each direction gets only a partial-slot allocation, so the usable transmission time for each side is limited compared to configurations that use full DL or UL slots.

In this configuration, sr_period is reduced to make the UE send Scheduling Request more frequently. The Scheduling Request is the signal the UE uses when it wants uplink resources but does not yet have a valid UL grant. If this request opportunity comes too rarely, the UE may need to wait longer before it can ask for uplink transmission. That extra waiting time directly increases uplink access delay and can make the overall latency worse.
By setting sr_period: 2, the UE gets SR opportunities every 2 slots. This short interval helps the UE request uplink resources more quickly, so the gNB can respond with a UL grant sooner. This is especially important in a short TDD cycle or latency-sensitive setup, where even a small scheduling delay can noticeably affect responsiveness.
So the main purpose of reducing sr_period is to shorten the waiting time before uplink scheduling can begin. If the UL grant is delayed because SR opportunities are too sparse, the total end-to-end latency becomes longer. A smaller sr_period helps avoid that problem and makes uplink access faster and more responsive.

PRACH Configuration is chosen in such a way that RO(RACH Occassion) is only on UL symbols. In this setup, the PRACH configuration is selected so that the RACH Occasion falls only within the uplink part of the TDD pattern. The key parameter is prach_config_index: 78. This value is chosen so that the allowed PRACH transmission opportunity is aligned with the UL symbols defined in the custom TDD configuration, instead of falling into flexible or downlink symbols.
The reason for this choice is practical. In theory, a UE may attempt PRACH on flexible symbols in a TDD UL/DL configuration. But in real testing, some UEs do not reliably transmit RACH on those flexible symbols. Because of that, it is safer to choose a PRACH configuration whose RACH Occasion is located strictly inside the definite uplink region. This avoids ambiguity and makes the random access procedure more robust.

In this setup, k_min is reduced to 2 so that the scheduling timing between downlink and uplink can be made more aggressive. In practice, this lowers the minimum timing gap used for parameters such as k1 and k2, which means the gNB can receive UE feedback sooner and can also schedule uplink transmission with less delay. As a result, the overall response time of the system becomes shorter, which is helpful when the main goal is to reduce latency.
The benefit of this smaller k_min is faster control loop timing. The gNB does not need to wait as long before getting HARQ feedback from the UE or before granting the next uplink transmission opportunity. This can improve responsiveness for both downlink acknowledgment handling and uplink resource scheduling. In a low-latency test scenario, that is often an important optimization because even a few extra slots of delay can noticeably increase the end-to-end turnaround time.
However, this kind of tighter scheduling also puts more pressure on the gNB processing chain. The base station has less time to decode incoming information, make scheduling decisions, prepare the response, and transmit it at the correct moment. That is why this setting usually requires strong CPU performance and a stable real-time execution environment. If the platform cannot keep up, the intended timing may be missed, which can lead to unstable behavior or degraded performance. So this parameter can improve latency, but it should be used only after confirming that the system has enough processing headroom and that real-time conditions are well maintained.

Put CSI RS for CSI Report at the first slot (slotoffset = 0) of each periods. This example shows how CSI-RS for CSI reporting is manually positioned so that it does not collide with SSB transmission. The main idea is to place the CSI-RS in the first slot of each reporting period by using slotoffset = 0, while carefully choosing the OFDM symbol location so that it stays outside the SSB symbols. In this case, the SSB bitmap is 10000000, which means the active SSB occupies symbols 2, 3, 4, and 5. For that reason, the CSI-RS is placed at symbol 6, so it comes immediately after the SSB region and avoids overlap.
Another important design point is the relation among first_symb, offset, and the slot location. These values must be chosen so that the different CSI-RS resources do not overlap with each other, do not collide with SSB, and still satisfy TRS timing requirements if the resource is used for TRS. In other words, the manual CSI-RS design is not just about enabling CSI measurement. It is also about placing each resource at a clean time-frequency location where it can coexist with SSB, SIB1, and any TRS-related constraints.
So the key message of this example is that the CSI-RS for CSI report is intentionally placed in the first slot of the period and at symbol 6 so that it avoids the SSB symbols occupying 2 through 5. The detailed mapping parameters are then chosen according to the number of downlink antennas, while additional CSI-RS resource IDs can be reserved for TRS with their own placement rules.
(
The parameters to be noted in this example are as follows : (NOTE : the detailed meaning of each of these parameter in terms of 3GPP, check out this note)
- frequency_domain_allocation, cdm_type : the configuration for csi_rs_id 0 is for CSI report and csi_rs_id 1,2,3,4 is to configure TRS.
- n_ports : this is set to be same as the number of DL Antenna for CSI report and set to 1 for TRS
- first_symb, offset : set these in such a way that does not overlap each other and set to meet TRS requirement if they are for TRS.

This PUSCH configuration is designed for a very short uplink region at the end of the slot. Here, start_symb: 10 means the PUSCH starts from OFDM symbol 10, and n_symb: 4 means it occupies only the last 4 symbols of the slot. This indicates that the TDD pattern leaves only a small uplink portion, so the PUSCH is explicitly placed inside that narrow UL window. If the UL symbol allocation in the TDD pattern changes, this PUSCH allocation should also be changed to keep it aligned with the actual uplink region.
The use of mapping_type: "typeB" is important here because Type B mapping is suitable when PUSCH starts in the middle or near the end of the slot rather than from the first symbol. That makes it a natural choice for this kind of partial-slot uplink transmission. In other words, the configuration is optimized for a short burst of uplink data instead of a full-slot PUSCH.
The parameter dmrs_add_pos: 0 means no additional DMRS symbols are inserted. This reduces overhead and leaves more of the limited 4-symbol uplink region available for actual data transmission. Since the PUSCH duration is very short, removing the extra DMRS can be acceptable in many cases. But if the PUSCH becomes longer or the radio condition is challenging, additional DMRS may be needed to improve channel estimation reliability.

Run and Check
Restart the lte service and launch the screen. Switch to (enb) and make it sure that you don't get any error message. If you use the configuration predefined in the configuration file, you may not get any error since they are already tested but if you modify it or define a new configuration, you may see some errors described in Common Errors section.

Collect the log with bcch and check the contents of SIB1. See if your configuration is properly relected into SIB1 as shown below. (
the key field is tdd-UL-DL-ConfigurationCommon. The screenshot shows that this field carries only pattern1, which means a single TDD pattern is being broadcast. Inside that pattern, dl-UL-TransmissionPeriodicity corresponds directly to the configured period. The values nrofDownlinkSlots and nrofDownlinkSymbols correspond to dl_slots and dl_symbols. The values nrofUplinkSlots and nrofUplinkSymbols correspond to ul_slots and ul_symbols. So by reading this section of SIB1, you can directly verify whether the intended UL/DL timing structure has been correctly reflected in the live RRC message.

RRC / NAS Signaling
SIB1 (SA)
: This is the SIB1 message sent by gNB to configure NR SA. (
{
message c1: systemInformationBlockType1: {
...
servingCellConfigCommon {
...
tdd-UL-DL-ConfigurationCommon {
referenceSubcarrierSpacing kHz30,
pattern1 {
dl-UL-TransmissionPeriodicity ms5,
nrofDownlinkSlots 7,
nrofDownlinkSymbols 6,
nrofUplinkSlots 2,
nrofUplinkSymbols 4
}
},
}
Common Errors
Case 1 : Collision between Uplink CSI-RS and NZP CSI-RS
This would be one of the most common error you may get when you try to apply your own configuration. NZP CSI-RS is a type of downlink reference signal. It cannot be transmitted in uplink slot. It mean your TDD UL/DL Config assigns some UL slot which is same as the slot where CSI-RS is transmitted.

You can fix this problem in a few different ways.
Method 1 : The simplest way would be to comment out following lines. With this, CSI-RS configuration would be omitted. So it would not collide with any UL slot in your configuration. This is the recommended way for most of the cases
Method 2 : If you want to transmit TRS CSI-RS with your own configuration, change following parameter for all the csi_rs configuration in such a way that those reference signal is transmitted via DL slots in your configuration

Tips
Guide line for Low Latency
We configure Low Latency mainly adjusting TDD UL/DL Configuration Common (TDD Pattern) to achieve the low latency (
- Reduce the periodicity and pack the DL/UL symbols with the periodicity (Ex, this test). This is relatively easy since you can easily visualize the configuration.
- Select appropriate PRACH configuration. In most of Low Latency TDD pattern, we usually schedule partial UL slots (i.e, no full slot UL, only a few symbols at the end of a slot). So you need to ensure to choose a proper PRACH configuration that falls into the short UL region. This is tricky because it is not easy to figure out (or visualize) the RO(RACH Occassion) symbols for each PRACH configuration. Refer to this note for the details.
- When there is no full slot UL, you need to configure carefully about pusch SLIV (i.e, mapping type B, start symbol, number of symbols) to ensure the scheduled PUSCH fall into UL region of TDD Pattern. This is not that difficult because you can easily visualize this configuration.
PUSCH Scheduling in special slot
In default configuration, PUSCH is not scheduled in special slot (i.e, the slot in which both DL and UL symbols are configured). The symbols in this slot is reserved for special uplink signal like SRS.
If you want to schedule PUSCH even for those special slots, you need to configure the parameter : partial_slots