Fronthaul#
ORAN fronthaul interface for C-Plane and U-Plane packet processing.
Overview#
The Fronthaul library provides ORAN (Open Radio Access Network) fronthaul processing for 5G Radio Units (RUs). It handles both Control-Plane (C-Plane) and User-Plane (U-Plane) packet flows with precise timing and low latency.
Key Features#
C-Plane Processing: Convert FAPI messages to ORAN C-Plane packets and transmit via DPDK
U-Plane Processing: Receive and reorder U-Plane packets using GPU- accelerated Order Kernel pipeline
YAML Configuration: Parse RU emulator configuration files
Timing Management: Calculate packet send times with nanosecond precision
Statistics Tracking: Monitor packets sent, errors, and throughput
Core Concepts#
C-Plane Configuration#
Configure the Fronthaul library with network settings, cell parameters, timing windows (T1a min/max), and antenna port configuration for ORAN C-Plane operation.
// Build fronthaul configuration
FronthaulConfig config{};
// Network configuration - NIC address
config.net_config.nic_config.nic_pcie_addr = "0000:17:00.0";
// Cell configuration - destination MACs and VLANs
config.cell_dest_macs.push_back({{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}});
config.cell_vlan_tcis.push_back(0xE002); // VLAN 2, PCP 7
// ORAN parameters
config.numerology = ran::oran::from_scs(ran::oran::SubcarrierSpacing::Scs30Khz);
config.num_antenna_ports = 4;
config.mtu = 1514;
// Timing parameters
config.slot_ahead = 1;
config.t1a_max_cp_ul_ns = 285'000; // 285us
config.t1a_min_cp_ul_ns = 234'000; // 234us
// Access configuration
const auto num_cells = config.cell_dest_macs.size();
const auto num_ports = config.num_antenna_ports;
const auto mtu_size = config.mtu;
U-Plane Configuration#
U-Plane configuration controls the Order Kernel pipeline for receiving and processing U-Plane packets. The configuration includes timing windows (Ta4 early/late), packet buffer sizes, and timeout parameters.
// Create U-Plane configuration with default settings
UPlaneConfig uplane_config{};
// Customize timing windows for 30kHz SCS
uplane_config.ta4_min_ns = 50'000; // 50us early window
uplane_config.ta4_max_ns = 450'000; // 450us late window
uplane_config.slot_duration_ns = 500'000; // 500us slot
// Configure packet reception
uplane_config.num_packets = 16384; // 16K packet buffers
uplane_config.max_packet_size = 8192; // 8KB max packet size
// Access configured values
const auto ta4_min = uplane_config.ta4_min_ns;
const auto ta4_max = uplane_config.ta4_max_ns;
const auto num_pkts = uplane_config.num_packets;
Packet Timing#
Accurate packet timing is critical for ORAN fronthaul. The library calculates packet send times based on slot timing, T1a windows (C-Plane timing advance window relative to data slot boundary), and TAI offset (International Atomic Time for GPS synchronization).
// Calculate packet send time for a slot
const PacketSendTimeParams params{
.t0 = 0ns,
.tai_offset = 0ns,
.absolute_slot = 100,
.slot_period = 500us,
.slot_ahead = 1,
.t1a_max_cp_ul = 285us,
.actual_start = 50ms};
const auto result = calculate_packet_send_time(params);
// Access timing results
const auto actual_start = result.actual_start;
const auto start_tx = result.start_tx;
Packet Headers#
ORAN C-Plane packets require proper Ethernet, VLAN, and eCPRI headers. The library provides a helper to create packet header templates.
// Create packet header template for ORAN C-Plane
const framework::net::MacAddress src_mac{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
const framework::net::MacAddress dest_mac{{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}};
const std::uint16_t vlan_tci = 0xE002; // VLAN 2, PCP 7
const std::uint16_t eac_id = 0; // Enhanced antenna carrier ID
const auto header = create_packet_header_template(src_mac, dest_mac, vlan_tci, eac_id);
// Header contains ethernet, VLAN, and eCPRI fields
const auto header_size = sizeof(header);
Statistics#
The Fronthaul class tracks operational statistics including packets sent, requests sent, errors, and average packets per request.
// Create statistics structure
FronthaulStats stats{};
stats.requests_sent = 1000;
stats.packets_sent = 4000;
stats.send_errors = 0;
stats.avg_packets_per_request = 4.0;
// Access statistics
const auto total_requests = stats.requests_sent;
const auto total_packets = stats.packets_sent;
const auto avg_packets = stats.avg_packets_per_request;
const auto errors = stats.send_errors;
Usage Example#
The Fronthaul library requires hardware resources (DPDK, NIC, GPU) for actual operation. The following examples are extracted from the complete sample application.
Fronthaul Configuration#
// 6. Create and return fronthaul config with complete net_config
static constexpr std::uint32_t SCS_KHZ = 30;
return ran::fronthaul::FronthaulConfig{
.net_config = net_config,
.cell_dest_macs = cell_macs,
.cell_vlan_tcis = cell_vlans,
.numerology = ran::oran::from_scs_khz(SCS_KHZ),
.slot_ahead = slot_ahead,
.t1a_max_cp_ul_ns = yaml_config->timing.t1a_max_ns,
.t1a_min_cp_ul_ns = yaml_config->timing.t1a_min_ns,
.uplane_config = uplane_config,
};
Fronthaul Construction#
// U-Plane configuration is already set in fh_config from create_fronthaul_config_from_yaml
RT_LOGC_INFO(
rf::FronthaulApp::UPlane,
"U-Plane configured: slot_duration={}ns, Ta4 window=[{}ns, {}ns], RU MAC={}",
fh_config.uplane_config.slot_duration_ns,
fh_config.uplane_config.ta4_min_ns,
fh_config.uplane_config.ta4_max_ns,
fh_config.cell_dest_macs[0].to_string());
// Create fronthaul instance (now handles both C-Plane and U-Plane)
rf::Fronthaul fronthaul(fh_config);
Sending C-Plane Messages#
// Send C-plane for this cell
// Request already has updated sfn/slot from FapiFileReplay
const auto &req_info = request_opt.value();
fronthaul.send_ul_cplane(
*req_info.request, req_info.body_len, cell_id, absolute_slot, t0, tai_offset);
Processing U-Plane#
// Get current slot timing and convert to ORAN format
const auto oran_slot_timing =
ran::oran::fapi_to_oran_slot_timing(fapi_replay.get_current_slot_timing());
try {
fronthaul.process_uplane(oran_slot_timing);
} catch (const std::exception &e) {
RT_LOGC_ERROR(rf::FronthaulApp::UPlane, "Failed to process U-Plane: {}", e.what());
}
Accessing Statistics#
RT_LOGC_INFO(rf::FronthaulApp::Stats, "\n=== Fronthaul Statistics ===");
RT_LOGC_INFO(rf::FronthaulApp::Stats, "{}", fronthaul.get_stats());
For the complete working example with task scheduling, timing
synchronization, and FAPI replay, see
ran/runtime/fronthaul/samples/fronthaul_app.cpp.
Additional Examples#
For more examples with executable code, see:
ran/runtime/fronthaul/tests/fronthaul_sample_tests.cpp- Configuration and utility examplesran/runtime/fronthaul/samples/fronthaul_app.cpp- Complete application with Fronthaul constructionran/runtime/fronthaul/samples/fronthaul_app_utils.cpp- C-Plane/U-Plane processing and statistics
API Reference#
-
constexpr std::size_t ran::fronthaul::ORDER_KERNEL_MAX_CELLS_PER_SLOT = 1#
Maximum number of cells that can be processed per slot.
-
constexpr std::uint32_t ran::fronthaul::DEFAULT_DPDK_CORE_ID = 0#
DPDK core for network operations (default: core 0 for receiver)
-
constexpr std::uint16_t ran::fronthaul::ORAN_ORU_ETHER_TYPE = 0xaefe#
O-RAN eCPRI EtherType used by production O-RUs.
-
constexpr std::uint64_t ran::fronthaul::DEFAULT_TIMEOUT_NO_PKT_NS = to_nanoseconds(std::chrono::milliseconds(6))#
Default timeout when no packets received (6 milliseconds)
-
constexpr std::uint64_t ran::fronthaul::DEFAULT_TIMEOUT_FIRST_PKT_NS = to_nanoseconds(std::chrono::microseconds(1'500))#
Default timeout for first packet reception (1500 microseconds)
-
constexpr std::uint64_t ran::fronthaul::DEFAULT_TIMEOUT_LOG_INTERVAL_NS = to_nanoseconds(std::chrono::seconds(1))#
Default log interval for timeout messages (1 second)
-
constexpr std::uint8_t ran::fronthaul::DEFAULT_TIMEOUT_LOG_ENABLE = 1#
Default timeout log enable flag (1=enabled, 0=disabled)
-
constexpr std::uint32_t ran::fronthaul::DEFAULT_MAX_RX_PKTS = 512#
Default maximum packets to receive per kernel call.
-
constexpr std::uint64_t ran::fronthaul::DEFAULT_RX_PKTS_TIMEOUT_NS = to_nanoseconds(std::chrono::microseconds(100))#
Default RX packet timeout between packets (100 microseconds)
-
constexpr std::uint32_t ran::fronthaul::MAX_ANTENNA_PORTS_PER_SLOT = 4#
Maximum number of antenna ports (eAxC IDs) per slot.
-
constexpr int ran::fronthaul::PUSCH_NUM_PRB = 273#
PUSCH resource configuration for 100MHz bandwidth.
Number of PRBs
-
constexpr int ran::fronthaul::NUM_ANTENNA_PORTS = 4#
Number of antenna ports.
-
constexpr int ran::fronthaul::PUSCH_RE_PER_PRB = 12#
Resource elements per PRB.
-
constexpr std::uint32_t ran::fronthaul::ORAN_PUSCH_SYMBOLS_X_SLOT = 14#
PUSCH symbols per slot.
-
constexpr std::size_t ran::fronthaul::PUSCH_REAL_IMAG = 2#
PUSCH tensor dimensions for TensorInfo (FP16 complex, real/imag interleaved)
Real + imaginary components
-
constexpr std::size_t ran::fronthaul::PUSCH_NUM_ELEMENTS = static_cast<std::size_t>(PUSCH_NUM_PRB) * PUSCH_RE_PER_PRB * ORAN_PUSCH_SYMBOLS_X_SLOT * NUM_ANTENNA_PORTS * PUSCH_REAL_IMAG#
Total number of FP16 elements in PUSCH buffer (273 × 12 × 14 × 4 × 2 = 366,912)
-
constexpr std::size_t ran::fronthaul::PUSCH_SIZE_BYTES = PUSCH_NUM_ELEMENTS * sizeof(__half)#
Total size of PUSCH buffer in bytes (366,912 × 2 = 733,824 bytes)
- PacketSendTimeResult ran::fronthaul::calculate_packet_send_time(
- const PacketSendTimeParams ¶ms,
Calculate packet send time for a slot
This function computes when C-plane packets should be transmitted to the NIC, accounting for processing advance time, T1a timing windows, and TAI offset.
This is exposed for unit testing purposes.
- Parameters:
params – [in] Input parameters for packet send time calculation
- Returns:
Packet send time calculation results
- ran::oran::PacketHeaderTemplate ran::fronthaul::create_packet_header_template(
- const framework::net::MacAddress &src_mac,
- const framework::net::MacAddress &dest_mac,
- std::uint16_t vlan_tci,
- std::uint16_t enhanced_antenna_carrier,
Create packet header template for ORAN C-Plane messages
- Parameters:
src_mac – [in] Source MAC address (from NIC)
dest_mac – [in] Destination MAC address
vlan_tci – [in] VLAN tag control information
enhanced_antenna_carrier – [in] Enhanced antenna carrier ID (encodes cell and antenna port)
- Returns:
Packet header template ready for ORAN flow
- ran::fronthaul::DECLARE_LOG_COMPONENT(
- FronthaulLog,
- FronthaulGeneral,
- FronthaulParser,
- FronthaulTiming,
- FronthaulNetwork,
- FapiFileReplay,
Declare logging components for fronthaul subsystem
- ran::fronthaul::DECLARE_LOG_COMPONENT(
- FronthaulKernels,
- OrderModule,
- OrderPipeline,
- OrderFactory,
- OrderMemory,
- OrderKernel,
- OrderDoca,
Fronthaul Kernels Logging Components
Defines component categories for fronthaul U-plane (order kernel). Organized by functional area for filtering and organization.
Order Kernel (U-plane) Components:
OrderModule: OrderKernelModule lifecycle, port configuration, execution
OrderPipeline: OrderKernelPipeline setup, routing, graph management
OrderFactory: Module and pipeline factory operations
OrderMemory: Memory allocation, GDRCopy buffer management, descriptors
OrderKernel: CUDA kernel launch, parameters, device function calls
OrderDoca: DOCA RX queue interaction, semaphore handling, packet processing
- ran::fronthaul::DECLARE_LOG_COMPONENT(
- FronthaulApp,
- App,
- UPlane,
- CPlane,
- Config,
- Stats,
Fronthaul Application Logging Components
Defines component categories for fronthaul sample application. Used for application-level logging in samples/ directory.
Components:
App: CLI parsing, initialization, application lifecycle
UPlane: U-Plane message processing
CPlane: C-Plane message processing
Config: YAML configuration parsing
Stats: Statistics display and reporting
- tl::expected<FronthaulYamlConfig, std::string> ran::fronthaul::parse_fronthaul_config(
- const std::filesystem::path &config_file_path,
Parse fronthaul configuration from RU emulator YAML file
Extracts:
Cell configurations (MAC addresses, VLANs)
O-RAN timing parameters (t1a_max, t1a_min in µs, converted to ns)
MTU size
- Parameters:
config_file_path – [in] Path to ru_emulator_config.yaml
- Returns:
Parsed configuration on success, error message on failure
- tl::expected<FronthaulYamlConfig, std::string> ran::fronthaul::parse_fronthaul_config_from_string(
- std::string_view yaml_content,
Parse fronthaul configuration from YAML string
- Parameters:
yaml_content – [in] YAML content as string
- Returns:
Parsed configuration on success, error message on failure
-
template<bool, uint8_t, uint8_t, int, int>
void ran::fronthaul::order_kernel_doca_single_subSlot_pingpong( - const OrderKernelStaticDescriptor *static_desc,
- const OrderKernelDynamicDescriptor *dynamic_desc,
Unified ORAN order kernel with descriptor-based interface
Template parameters used by OrderKernelModule:
ok_tb_enable = false (no test bench)
ul_rx_pkt_tracing_level = 0 (no packet tracing)
srs_enable = 0 (PUSCH only)
NUM_THREADS = 320
NUM_CTAS_PER_SM = 1
- Parameters:
static_desc – [in] Static kernel parameters (GDRCopy buffers, DOCA handles)
dynamic_desc – [in] Dynamic kernel parameters (timing, frame/slot IDs)
-
template<typename Rep, typename Period>
constexpr std::uint64_t ran::fronthaul::to_nanoseconds(
)# Convert duration to nanoseconds at compile-time
- Template Parameters:
Rep – Arithmetic type representing the number of ticks
Period – std::ratio representing the tick period
- Parameters:
duration – [in] Duration to convert
- Returns:
Duration value in nanoseconds
- void ran::fronthaul::populate_uplane_env_config(
- framework::net::EnvConfig &config,
- const FronthaulYamlConfig &yaml_config,
- const UPlaneConfig &uplane_config,
Populate network environment configuration with U-Plane DOCA RX queue settings
Adds DOCA GPUNetIO RX queue configuration to an existing EnvConfig for receiving O-RAN U-Plane packets with GPU-accelerated packet processing via the Order Kernel pipeline.
The input EnvConfig must already contain:
nic_pcie_addr (from C-plane configuration)
gpu_device_id (from C-plane configuration)
DPDK configuration (from C-plane configuration)
This function adds:
DOCA RX queue with O-RAN eCPRI EtherType filtering
GPU semaphore setup for packet metadata communication
MAC address filtering for RU identification
- Parameters:
config – [inout] Existing EnvConfig (with C-plane settings) to populate with U-plane DOCA RX queue
yaml_config – [in] Parsed YAML configuration containing RU MAC address
uplane_config – [in] U-Plane configuration parameters (timing, DOCA settings)
- Throws:
std::invalid_argument – if configuration parameters are invalid
-
struct CellConfig#
- #include <fronthaul_parser.hpp>
Per-cell configuration from YAML
-
struct DocaOrderSemInfo#
- #include <order_kernel_descriptors.hpp>
DOCA semaphore info structure for order kernel.
This structure is passed through DOCA GPUNetIO semaphores to communicate packet metadata from the NIC to the GPU order kernel.
Public Members
-
std::uint32_t pkts = {}#
Number of packets received.
-
std::uint32_t pkts = {}#
-
class Fronthaul : public framework::pipeline::IPipelineOutputProvider#
- #include <fronthaul.hpp>
Fronthaul library main class
Manages ORAN fronthaul operations including:
Converting FAPI to ORAN C-Plane messages
Transmitting C-Plane packets via DPDK
Processing U-Plane packets via Order Kernel pipeline
This class is stateless - all timing and request data comes from caller. Use send_ul_cplane() to transmit C-Plane messages for each cell/slot. Use process_uplane() to execute the Order Kernel pipeline.
Implements IPipelineOutputProvider to expose Order Kernel output addresses for zero-copy integration with downstream pipelines.
Public Functions
-
explicit Fronthaul(const FronthaulConfig &config)#
Construct fronthaul library
Sets up network environment and creates ORAN flows. All setup happens in constructor - ready to use immediately.
- Parameters:
config – [in] Fronthaul configuration
- Throws:
std::runtime_error – if setup fails
std::invalid_argument – if configuration is invalid
-
~Fronthaul() override = default#
Destructor
Cleans up resources including CUDA stream if U-Plane was configured.
- void send_ul_cplane(
- const scf_fapi_ul_tti_req_t &request,
- std::size_t body_len,
- std::uint16_t cell_id,
- std::uint64_t absolute_slot,
- std::chrono::nanoseconds t0,
- std::chrono::nanoseconds tai_offset,
Send uplink C-Plane messages for a cell
Converts FAPI UL_TTI_REQUEST to ORAN C-Plane messages and transmits them. The request must already have sfn and slot fields updated to match the desired transmission timing.
- Parameters:
request – [in] FAPI UL_TTI_REQUEST message with updated timing fields
body_len – [in] Size of FAPI message request body (excluding body header)
cell_id – [in] Cell identifier (index into cell_dest_macs)
absolute_slot – [in] Absolute slot number for timing calculation
t0 – [in] Time for system frame 0, subframe 0, slot 0
tai_offset – [in] TAI offset for time synchronization
-
void process_uplane(ran::oran::OranSlotTiming timing)#
Process U-Plane for the current slot
Executes the Order Kernel pipeline to receive and process U-Plane packets. Timing is passed by value to avoid threading issues (U-plane processing is asynchronous).
- Parameters:
timing – [in] ORAN slot timing (frame, subframe, slot)
-
inline const FronthaulConfig &config() const noexcept#
Get configuration
- Returns:
Reference to fronthaul configuration
-
FronthaulStats get_stats() const noexcept#
Get fronthaul statistics
- Returns:
Current statistics snapshot
-
void reset_stats() noexcept#
Reset statistics counters to zero
Resets all statistics counters (requests_sent, packets_sent, send_errors) to zero. Useful for test scenarios where fresh statistics are needed.
-
OrderKernelStatistics read_kernel_statistics() const#
Read accumulated kernel statistics from U-Plane processing
Retrieves accumulated PRB counts across all processed slots.
- Throws:
std::runtime_error – if U-Plane is not initialized
- Returns:
OrderKernelStatistics with accumulated counts
- inline OrderKernelPipeline *get_order_kernel_pipeline(
Get Order Kernel pipeline pointer
Provides non-owning access to the Order Kernel pipeline for integration with Driver. The pipeline remains owned by Fronthaul and must not be deleted by the caller.
- Returns:
Non-owning pointer to OrderKernelPipeline, or nullptr if U-Plane not initialized
- inline virtual std::span<const framework::pipeline::PortInfo> get_order_kernel_outputs(
Get Order Kernel output addresses
Implements IPipelineOutputProvider::get_order_kernel_outputs().
Provides access to the stable output buffer addresses captured after Order Kernel warmup. These addresses can be used for zero-copy data passing to downstream pipelines (e.g., PUSCH pipeline).
The addresses are captured once after Order Kernel initialization and remain valid throughout the Fronthaul lifetime.
- Returns:
Span of PortInfo describing Order Kernel outputs, or empty span if U-Plane not initialized
-
struct OrderKernelStatistics#
- #include <fronthaul.hpp>
Order kernel accumulated statistics across all slots
Public Members
-
std::uint64_t total_pusch_prbs = {}#
Accumulated PUSCH PRBs across all slots.
-
std::uint64_t total_prach_prbs = {}#
Accumulated PRACH PRBs across all slots.
-
std::uint64_t total_srs_prbs = {}#
Accumulated SRS PRBs across all slots.
-
std::uint64_t total_expected_prbs = {}#
Accumulated expected PRBs across all slots.
-
std::uint64_t slots_processed = {}#
Number of U-Plane slots processed.
-
std::uint64_t total_pusch_prbs = {}#
-
struct FronthaulConfig#
- #include <fronthaul.hpp>
Configuration for fronthaul library
Public Members
-
framework::net::EnvConfig net_config = {}#
Network environment configuration.
-
std::vector<framework::net::MacAddress> cell_dest_macs#
Destination MAC addresses per cell.
-
std::vector<std::uint16_t> cell_vlan_tcis#
VLAN TCI per cell.
-
ran::oran::OranNumerology numerology = {ran::oran::from_scs(ran::oran::SubcarrierSpacing::Scs30Khz)}#
ORAN numerology configuration.
-
std::uint32_t num_antenna_ports = {4}#
Number of antenna ports.
-
std::uint16_t mtu = {DEFAULT_MTU}#
Maximum transmission unit size.
-
std::uint32_t slot_ahead = {1}#
Slots to process ahead.
-
std::uint64_t t1a_max_cp_ul_ns = {}#
T1a max window for uplink C-plane.
-
std::uint64_t t1a_min_cp_ul_ns = {}#
T1a min window for uplink C-plane.
-
std::uint64_t tx_cell_start_offset_ns = {0}#
Optional per-cell offset.
-
std::int64_t gps_alpha = {0}#
GPS alpha timing parameter.
-
std::int64_t gps_beta = {0}#
GPS beta timing parameter.
-
UPlaneConfig uplane_config = {}#
U-Plane Order Kernel pipeline configuration.
Public Static Attributes
-
static constexpr std::uint16_t DEFAULT_MTU = 1514#
Default MTU size in bytes.
-
framework::net::EnvConfig net_config = {}#
-
struct FronthaulStats#
- #include <fronthaul.hpp>
Fronthaul statistics
Note
This struct contains a snapshot of statistics at a point in time. The Fronthaul class maintains atomic counters internally and get_stats() returns a consistent snapshot.
-
struct FronthaulYamlConfig#
- #include <fronthaul_parser.hpp>
Fronthaul configuration parsed from RU emulator YAML
Public Members
-
std::vector<CellConfig> cells#
Per-cell configuration.
-
OranTimingConfig timing = {}#
O-RAN timing parameters.
-
std::uint32_t mtu_size = {}#
MTU size for network config.
-
std::vector<CellConfig> cells#
-
struct OranTimingConfig#
- #include <fronthaul_parser.hpp>
O-RAN timing parameters from YAML
Note: Timing values in the YAML file are specified in microseconds (µs) and are automatically converted to nanoseconds during parsing.
-
struct OrderKernelDynamicDescriptor#
- #include <order_kernel_descriptors.hpp>
Dynamic kernel parameters (can change per iteration)
Parameters in this structure are updated every slot/subframe via configure_io(). This includes timing parameters, packet statistics, and timeout configuration.
Strategy: When unsure if a parameter is static or dynamic → make it dynamic (safer).
Public Members
-
std::uint8_t frame_id = {0}#
Current frame ID (0-255)
-
std::uint8_t subframe_id = {0}#
Current subframe ID (0-9, 10 subframes per frame)
-
std::uint8_t slot_id = {0}#
Current slot ID (varies by numerology, e.g., 0-1 for 30kHz SCS)
-
std::array<std::uint64_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> slot_start = {}#
Slot start time in nanoseconds (system timestamp)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> early_rx_packets = {}#
Early packet count (current slot, GPU writes via GDRCopy)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> on_time_rx_packets = {}#
On-time packet count (current slot)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> late_rx_packets = {}#
Late packet count (current slot)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_early_rx_packets = {}#
Early packet count (next slot)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_on_time_rx_packets = {}#
On-time packet count (next slot)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_late_rx_packets = {}#
Late packet count (next slot)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rx_packets_dropped_count = {}#
Dropped packet count (always used, even when tracing disabled)
-
std::array<std::uint64_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> order_kernel_last_timeout_error_time = {}#
Last timeout error timestamp.
-
std::uint8_t frame_id = {0}#
-
class OrderKernelModule : public framework::pipeline::IModule, public framework::pipeline::IAllocationInfoProvider, public framework::pipeline::IGraphNodeProvider, public framework::pipeline::IStreamExecutor#
- #include <order_kernel_module.hpp>
OrderKernelModule - ORAN UL Receiver Order Kernel
Wraps the order_kernel_doca_single_subSlot_pingpong CUDA kernel for ORAN packet reception, ordering, and decompression.
Configuration:
1 input port: “doca_objects” (DOCA RX queue parameters, zero-copy)
1 output port: “pusch” (PUSCH IQ data buffer pointer)
Custom CUDA kernel for packet processing on GPU
GDRCopy memory for NIC↔GPU direct access
Public Functions
- explicit OrderKernelModule(
- std::string instance_id,
- const StaticParams ¶ms,
Construct module with instance ID and parameters
- Parameters:
instance_id – [in] Unique identifier for this module instance
params – [in] Static configuration parameters
- Throws:
gsl::fail_fast – if preconditions are violated
- Pre:
params.gdr_handle must not be null
- Pre:
params.doca_rxq_params must not be null
-
~OrderKernelModule() override = default#
-
OrderKernelModule(const OrderKernelModule&) = delete#
-
OrderKernelModule &operator=(const OrderKernelModule&) = delete#
-
OrderKernelModule(OrderKernelModule&&) = delete#
-
OrderKernelModule &operator=(OrderKernelModule&&) = delete#
-
inline virtual std::string_view get_type_id() const override#
Get module type identifier
- Returns:
Module type string “order_kernel_module”
-
inline virtual std::string_view get_instance_id() const override#
Get module instance identifier
- Returns:
Instance ID provided at construction
- virtual framework::pipeline::IStreamExecutor *as_stream_executor(
Get stream executor interface
- Returns:
Pointer to IStreamExecutor interface (this module)
- virtual framework::pipeline::IGraphNodeProvider *as_graph_node_provider(
Get graph node provider interface
- Returns:
Pointer to IGraphNodeProvider interface (this module)
- virtual std::vector<std::string> get_input_port_names(
Get input port names
- Returns:
Vector containing “doca_objects”
- virtual std::vector<std::string> get_output_port_names(
Get output port names
- Returns:
Vector containing “pusch”
- virtual std::vector<framework::tensor::TensorInfo> get_input_tensor_info(
- std::string_view port_name,
Get input tensor information for specified port
- Parameters:
port_name – [in] Input port name
- Returns:
Vector of tensor info for the port
- virtual std::vector<framework::tensor::TensorInfo> get_output_tensor_info(
- std::string_view port_name,
Get output tensor information for specified port
- Parameters:
port_name – [in] Output port name
- Returns:
Vector of tensor info for the port
- virtual framework::pipeline::InputPortMemoryCharacteristics get_input_memory_characteristics(
- std::string_view port_name,
Get input memory characteristics for specified port
- Parameters:
port_name – [in] Input port name
- Returns:
Memory characteristics for the port
- virtual framework::pipeline::OutputPortMemoryCharacteristics get_output_memory_characteristics(
- std::string_view port_name,
Get output memory characteristics for specified port
- Parameters:
port_name – [in] Output port name
- Returns:
Memory characteristics for the port
- virtual framework::pipeline::ModuleMemoryRequirements get_requirements(
Get module memory requirements
- Returns:
Memory requirements for descriptors and buffers
- virtual void setup_memory(
- const framework::pipeline::ModuleMemorySlice &memory_slice,
Allocate and initialize module memory
- Parameters:
memory_slice – [in] Memory slice allocated by framework
- virtual void set_inputs(
- std::span<const framework::pipeline::PortInfo> inputs,
Configure input port connections.
- Parameters:
inputs – [in] Input port information containing DOCA objects
-
virtual void warmup(cudaStream_t stream) override#
Perform warmup operations
- Parameters:
stream – [in] CUDA stream for warmup operations
- virtual void configure_io(
- const framework::pipeline::DynamicParams ¶ms,
- cudaStream_t stream,
Configure I/O for current iteration
- Parameters:
params – [in] Dynamic parameters for this iteration
stream – [in] CUDA stream for async operations during configuration
- virtual std::vector<framework::pipeline::PortInfo> get_outputs(
Get output port information
- Returns:
Vector of output port info
-
virtual void execute(cudaStream_t stream) override#
Execute kernel in stream mode
- Parameters:
stream – [in] CUDA stream for kernel execution
- virtual std::span<const CUgraphNode> add_node_to_graph(
- gsl_lite::not_null<framework::pipeline::IGraph*> graph,
- std::span<const CUgraphNode> deps,
Add order kernel node to CUDA graph.
- Parameters:
graph – [in] Graph interface for node creation
deps – [in] Dependency nodes that must complete before this node
- Returns:
Span of created graph node handle (single order kernel node)
- virtual void update_graph_node_params(
- CUgraphExec exec,
- const framework::pipeline::DynamicParams ¶ms,
Update graph node parameters
- Parameters:
exec – [in] CUDA graph executable handle
params – [in] Dynamic parameters for update
-
OrderKernelResults read_kernel_results() const#
Read kernel execution results from GDRCopy memory
This method reads the kernel results directly from CPU-visible GPU memory without requiring GPU synchronization. Should be called after kernel execution completes.
- Returns:
OrderKernelResults structure with current values
-
struct OrderKernelResults#
- #include <order_kernel_module.hpp>
Kernel execution results structure
Public Members
-
std::uint32_t exit_condition = {}#
Kernel exit condition code.
-
std::uint32_t pusch_ordered_prbs = {}#
Number of PUSCH PRBs processed.
-
std::uint32_t prach_ordered_prbs = {}#
Number of PRACH PRBs processed.
-
std::uint32_t srs_ordered_prbs = {}#
Number of SRS PRBs processed.
-
std::uint32_t expected_prbs = {}#
Expected total PRBs for this slot.
-
std::uint32_t exit_condition = {}#
-
struct StaticParams#
- #include <order_kernel_module.hpp>
Static parameters for module construction
Public Members
-
framework::pipeline::ExecutionMode execution_mode = {framework::pipeline::ExecutionMode::Stream}#
Pipeline execution mode (default: Stream)
-
gdr_t gdr_handle = {nullptr}#
Non-owning GDRCopy handle (gdr_t is already a pointer)
-
const framework::net::DocaRxQParams *doca_rxq_params{nullptr}#
DOCA RX queue parameters (must not be null)
-
TimingParams timing = {}#
ORAN timing windows (Ta4 early/late thresholds, slot duration)
-
std::vector<std::uint16_t> eaxc_ids = {0, 1, 2, 3}#
UL eAxC IDs for antenna ports.
-
framework::pipeline::ExecutionMode execution_mode = {framework::pipeline::ExecutionMode::Stream}#
-
struct TimingParams#
- #include <order_kernel_module.hpp>
Timing window parameters for ORAN packet processing
These values correspond to the ORAN timing specification and are typically loaded from YAML configuration (Ta4_min_ns, Ta4_max_ns in cuphycontroller config).
Public Members
-
std::uint64_t slot_duration_ns = {DEFAULT_SLOT_DURATION_NS}#
Slot duration in nanoseconds (default: 500us for 30kHz SCS)
-
std::uint64_t ta4_min_ns = {DEFAULT_TA4_MIN_NS}#
Ta4 early window - packets before slot_start + ta4_min are early (default: 50us)
-
std::uint64_t ta4_max_ns = {DEFAULT_TA4_MAX_NS}#
Ta4 late window - packets after slot_start + ta4_max are late (default: 450us)
Public Static Attributes
-
static constexpr std::uint64_t DEFAULT_SLOT_DURATION_NS = 500'000#
Default slot duration for 30kHz SCS (500 microseconds)
-
static constexpr std::uint64_t DEFAULT_TA4_MIN_NS = 50'000#
Default Ta4 early window (50 microseconds)
-
static constexpr std::uint64_t DEFAULT_TA4_MAX_NS = 450'000#
Default Ta4 late window (450 microseconds)
-
std::uint64_t slot_duration_ns = {DEFAULT_SLOT_DURATION_NS}#
-
class OrderKernelModuleFactory : public framework::pipeline::IModuleFactory#
- #include <order_kernel_factories.hpp>
Factory for creating OrderKernelModule instances
Creates modules of type “order_kernel_module” using the factory pattern.
Public Functions
-
OrderKernelModuleFactory() = default#
-
~OrderKernelModuleFactory() override = default#
-
OrderKernelModuleFactory(const OrderKernelModuleFactory&) = delete#
- OrderKernelModuleFactory &operator=(
- const OrderKernelModuleFactory&,
-
OrderKernelModuleFactory(OrderKernelModuleFactory&&) = default#
Move constructor
- OrderKernelModuleFactory &operator=( ) = default#
Move assignment operator
- Returns:
Reference to this object
- virtual std::unique_ptr<framework::pipeline::IModule> create_module(
- std::string_view module_type,
- const std::string &instance_id,
- const std::any &static_params,
Create an OrderKernelModule instance
- Parameters:
module_type – [in] Module type identifier (must be “order_kernel_module”)
instance_id – [in] Unique instance identifier
static_params – [in] Static parameters (OrderKernelModule::StaticParams)
- Throws:
std::invalid_argument – if module_type is not supported
std::bad_any_cast – if static_params has wrong type
- Returns:
Unique pointer to created module
- virtual bool supports_module_type(
- std::string_view module_type,
Check if factory supports the given module type
- Parameters:
module_type – [in] Module type to check
- Returns:
true if module_type is “order_kernel_module”
- std::unique_ptr<ran::fronthaul::OrderKernelModule> create_order_kernel_module(
- const std::string &instance_id,
- const std::any &static_params,
Create an OrderKernelModule instance with specific return type
Convenience method that returns the specific module type without requiring a cast. This is a non-virtual wrapper around the virtual create_module() method.
- Parameters:
instance_id – [in] Unique instance identifier
static_params – [in] Static parameters (OrderKernelModule::StaticParams)
- Throws:
std::bad_any_cast – if static_params has wrong type
- Returns:
Unique pointer to created OrderKernelModule
-
OrderKernelModuleFactory() = default#
-
class OrderKernelPipeline : public framework::pipeline::IPipeline#
- #include <order_kernel_pipeline.hpp>
OrderKernelPipeline - ORAN UL Receiver Pipeline
Single-module pipeline for ORAN packet reception and processing:
External Input (DOCA objects) ─→ OrderKernelModule ─→ External Output (PUSCH data)
Features:
Single OrderKernelModule wrapping order_kernel_doca_single_subSlot_pingpong
Stream and graph execution modes
GDRCopy memory management for NIC↔GPU communication
External DOCA input handling
Public Functions
- OrderKernelPipeline(
- std::string pipeline_id,
- std::unique_ptr<framework::pipeline::IModuleFactory> module_factory,
- const framework::pipeline::PipelineSpec &spec,
- const framework::net::DocaRxQParams *doca_rxq_params,
Construct OrderKernelPipeline using factory pattern
Creates the OrderKernelModule via the provided factory and configures the pipeline according to the PipelineSpec.
- Parameters:
pipeline_id – [in] Unique identifier for pipeline instance
module_factory – [in] Factory for creating modules (takes ownership)
spec – [in] Pipeline specification with module configuration
doca_rxq_params – [in] DOCA RX queue parameters (non-owning pointer, must outlive pipeline)
- Throws:
std::invalid_argument – if spec doesn’t have exactly 1 module or doca_rxq_params is null
std::runtime_error – if module creation fails or GDRCopy init fails
-
~OrderKernelPipeline() override = default#
-
OrderKernelPipeline(const OrderKernelPipeline&) = delete#
-
OrderKernelPipeline &operator=(const OrderKernelPipeline&) = delete#
-
OrderKernelPipeline(OrderKernelPipeline&&) = delete#
-
OrderKernelPipeline &operator=(OrderKernelPipeline&&) = delete#
-
inline virtual std::string_view get_pipeline_id() const override#
Get pipeline identifier
- Returns:
Pipeline ID string
-
inline virtual std::size_t get_num_external_inputs() const override#
Get number of external inputs
- Returns:
Number of external inputs (1 for DOCA objects)
-
inline virtual std::size_t get_num_external_outputs() const override#
Get number of external outputs
- Returns:
Number of external outputs (1 for PUSCH buffer)
- virtual std::vector<framework::pipeline::PortInfo> get_outputs(
Get pipeline output port information
Provides access to Order Kernel’s output buffer addresses. These addresses are stable after warmup() and can be used for zero-copy data passing to downstream pipelines (e.g., PUSCH).
- Throws:
std::runtime_error – if module not initialized
- Returns:
Vector containing one PortInfo with PUSCH buffer information
-
virtual void setup() override#
Perform pipeline setup
Allocates memory and initializes all modules
-
virtual void warmup(cudaStream_t stream) override#
Perform warmup operations
- Parameters:
stream – [in] CUDA stream for warmup operations
- virtual void configure_io(
- const framework::pipeline::DynamicParams ¶ms,
- std::span<const framework::pipeline::PortInfo> external_inputs,
- std::span<framework::pipeline::PortInfo> external_outputs,
- cudaStream_t stream,
Configure pipeline I/O for the current iteration.
- Parameters:
params – [in] Dynamic parameters for this iteration
external_inputs – [in] External input port information (DOCA objects)
external_outputs – [out] External output port information to populate
stream – [in] CUDA stream for any necessary operations
-
virtual void execute_stream(cudaStream_t stream) override#
Execute pipeline in stream mode
- Parameters:
stream – [in] CUDA stream for execution
-
virtual void execute_graph(cudaStream_t stream) override#
Execute pipeline in graph mode
- Parameters:
stream – [in] CUDA stream for graph execution
-
OrderKernelModule::OrderKernelResults read_kernel_results() const#
Read kernel execution results from the OrderKernelModule
This method provides access to kernel results including exit condition and PRB counts. Should be called after kernel execution completes.
- Throws:
std::runtime_error – if module is not available or not an OrderKernelModule
- Returns:
OrderKernelModule::OrderKernelResults structure with current values
-
class OrderKernelPipelineFactory : public framework::pipeline::IPipelineFactory#
- #include <order_kernel_factories.hpp>
Factory for creating OrderKernelPipeline instances
Creates pipelines of type “order_kernel_pipeline” using the factory pattern. Each pipeline gets its own dedicated OrderKernelModuleFactory instance.
Public Functions
-
OrderKernelPipelineFactory() = default#
-
~OrderKernelPipelineFactory() override = default#
-
OrderKernelPipelineFactory(const OrderKernelPipelineFactory&) = delete#
- OrderKernelPipelineFactory &operator=(
- const OrderKernelPipelineFactory&,
-
OrderKernelPipelineFactory(OrderKernelPipelineFactory&&) = default#
Move constructor
- OrderKernelPipelineFactory &operator=( ) = default#
Move assignment operator
- Returns:
Reference to this object
- virtual std::unique_ptr<framework::pipeline::IPipeline> create_pipeline(
- std::string_view pipeline_type,
- const std::string &pipeline_id,
- const framework::pipeline::PipelineSpec &spec,
Create an OrderKernelPipeline instance
- Parameters:
pipeline_type – [in] Pipeline type identifier (must be “order_kernel_pipeline”)
pipeline_id – [in] Unique pipeline identifier
spec – [in] Pipeline specification
- Throws:
std::invalid_argument – if pipeline_type is not supported or spec is invalid
- Returns:
Unique pointer to created pipeline
- virtual bool is_pipeline_type_supported(
- std::string_view pipeline_type,
Check if factory supports the given pipeline type
- Parameters:
pipeline_type – [in] Pipeline type to check
- Returns:
true if pipeline_type is “order_kernel_pipeline”
- virtual std::vector<std::string> get_supported_pipeline_types(
Get list of supported pipeline types
- Returns:
Vector containing “order_kernel_pipeline”
- inline void set_doca_params(
- const framework::net::DocaRxQParams *doca_params,
Set DOCA RX queue parameters for pipeline creation
Must be called before create_pipeline() to provide infrastructure handles.
- Parameters:
doca_params – [in] DOCA RX queue parameters (non-owning pointer, must outlive factory)
- std::unique_ptr<ran::fronthaul::OrderKernelPipeline> create_order_kernel_pipeline(
- const std::string &pipeline_id,
- const framework::pipeline::PipelineSpec &spec,
Create an OrderKernelPipeline instance with specific return type
Convenience method that returns the specific pipeline type without requiring a cast. This is a non-virtual wrapper around the virtual create_pipeline() method.
- Parameters:
pipeline_id – [in] Unique pipeline identifier
spec – [in] Pipeline specification
- Throws:
std::runtime_error – if DOCA params not set or pipeline creation fails
- Returns:
Unique pointer to created OrderKernelPipeline
-
OrderKernelPipelineFactory() = default#
-
struct OrderKernelStaticDescriptor#
- #include <order_kernel_descriptors.hpp>
Static kernel parameters (set once during setup)
Parameters in this structure are initialized during module setup and remain constant throughout the pipeline’s lifetime. This includes DOCA objects, cell configuration, buffer pointers, and GDRCopy device addresses.
Based on OrderKernelConfigParamsT from test_oran_order_kernel.cpp
Public Members
-
std::array<doca_gpu_eth_rxq*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rxq_info_gpu = {}#
DOCA RX queue device pointers (from DOCA GPUNetIO)
-
std::array<doca_gpu_semaphore_gpu*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> sem_gpu = {}#
DOCA semaphore GPU objects for packet ordering.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> sem_order_num = {}#
Semaphore item count (must be power of 2)
-
std::array<int, ORDER_KERNEL_MAX_CELLS_PER_SLOT> cell_id = {}#
Cell identifier (0 for single-cell)
-
std::array<int, ORDER_KERNEL_MAX_CELLS_PER_SLOT> comp_meth = {}#
Compression method (1=BFP)
-
std::array<int, ORDER_KERNEL_MAX_CELLS_PER_SLOT> bit_width = {}#
BFP bit width (14 for BFP14)
-
std::array<int, ORDER_KERNEL_MAX_CELLS_PER_SLOT> ru_type = {}#
RU type (2=FXCN O-RU specific handling)
-
std::array<float, ORDER_KERNEL_MAX_CELLS_PER_SLOT> beta = {}#
Beta scaling factor for BFP decompression (0.000244 for BFP14)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> start_cuphy_d = {}#
PHY start signal (CPU → GPU via GDRCopy)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> order_kernel_exit_cond_d = {}#
Kernel exit condition status (GPU → CPU via GDRCopy)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> last_sem_idx_rx_h = {}#
Last RX semaphore index (device memory)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> last_sem_idx_order_h = {}#
Last order semaphore index (device memory)
-
std::array<std::uint16_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_e_ax_c_map = {}#
Antenna port (eAxC ID) mapping (GDRCopy-backed)
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_e_ax_c_num = {}#
Number of antenna ports (4 for 4x4 MIMO)
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_buffer = {}#
PUSCH output buffer (device memory)
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_prb_x_slot = {}#
PRBs per slot (273 for 100MHz bandwidth)
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_prb_x_symbol = {}#
PRBs per symbol.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_prb_x_symbol_x_antenna = {}#
PRBs per symbol per antenna.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_prb_stride = {}#
PRB stride in bytes (273 * 48 bytes for 100MHz BW)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pusch_ordered_prbs = {}#
Ordered PRB counter (GDRCopy-backed for CPU visibility)
-
std::array<std::uint16_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_e_ax_c_map = {}#
PRACH antenna port mapping (GDRCopy-backed)
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_e_ax_c_num = {}#
Number of PRACH antenna ports.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_buffer_0 = {}#
PRACH FDM occasion 0 buffer.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_buffer_1 = {}#
PRACH FDM occasion 1 buffer.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_buffer_2 = {}#
PRACH FDM occasion 2 buffer.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_buffer_3 = {}#
PRACH FDM occasion 3 buffer.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_prb_x_slot = {}#
PRACH PRBs per slot.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_prb_x_symbol = {}#
PRACH PRBs per symbol.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_prb_x_symbol_x_antenna = {}#
PRACH PRBs per symbol per antenna.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_prb_stride = {}#
PRACH PRB stride in bytes.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> prach_ordered_prbs = {}#
PRACH ordered PRB counter (GDRCopy-backed)
-
std::array<std::uint16_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_e_ax_c_map = {}#
SRS antenna port mapping (GDRCopy-backed)
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_e_ax_c_num = {}#
Number of SRS antenna ports.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_buffer = {}#
SRS output buffer.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_prb_x_slot = {}#
SRS PRBs per slot.
-
std::array<std::uint32_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_prb_stride = {}#
SRS PRB stride in bytes.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_ordered_prbs = {}#
SRS ordered PRB counter (GDRCopy-backed)
-
std::array<std::uint8_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> srs_start_sym = {}#
SRS start symbol index.
-
std::uint32_t *sym_ord_done_sig_arr = {nullptr}#
Symbol ordering done signal array.
-
std::uint32_t *sym_ord_done_mask_arr = {nullptr}#
Symbol ordering done mask array.
-
std::uint32_t *pusch_prb_symbol_map_d = {nullptr}#
PUSCH PRB-to-symbol mapping.
-
std::uint32_t *num_order_cells_sym_mask_arr = {nullptr}#
Number of order cells symbol mask array.
-
std::array<std::uint64_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> ta4_min_ns = {}#
Early packet threshold (Ta4_min in ORAN spec, nanoseconds)
-
std::array<std::uint64_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> ta4_max_ns = {}#
Late packet threshold (Ta4_max in ORAN spec, nanoseconds)
-
std::array<std::uint64_t, ORDER_KERNEL_MAX_CELLS_PER_SLOT> slot_duration = {}#
Slot duration in nanoseconds (e.g., 500us for 30kHz SCS)
-
std::uint64_t timeout_no_pkt_ns = {DEFAULT_TIMEOUT_NO_PKT_NS}#
Timeout if no packets received (nanoseconds, default 6 seconds)
-
std::uint64_t timeout_first_pkt_ns = {DEFAULT_TIMEOUT_FIRST_PKT_NS}#
Timeout for first packet (nanoseconds, default 1500 microseconds)
-
std::uint64_t timeout_log_interval_ns = {DEFAULT_TIMEOUT_LOG_INTERVAL_NS}#
Log interval for timeout messages (nanoseconds, default 1 second)
-
std::uint8_t timeout_log_enable = {DEFAULT_TIMEOUT_LOG_ENABLE}#
Enable timeout logging (1=enable, 0=disable)
-
std::uint32_t max_rx_pkts = {DEFAULT_MAX_RX_PKTS}#
Maximum packets to receive per call (default 100)
-
std::uint64_t rx_pkts_timeout_ns = {DEFAULT_RX_PKTS_TIMEOUT_NS}#
RX packet timeout (nanoseconds, default 100 microseconds)
-
std::array<std::uint64_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rx_packets_ts = {}#
Packet timestamps per symbol.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rx_packets_count = {}#
Packet counts per symbol.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rx_bytes_count = {}#
Byte counts per symbol.
-
std::array<std::uint64_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rx_packets_ts_earliest = {}#
Earliest packet timestamp.
-
std::array<std::uint64_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rx_packets_ts_latest = {}#
Latest packet timestamp.
-
std::array<std::uint64_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_rx_packets_ts = {}#
Next slot packet timestamps.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_rx_packets_count = {}#
Next slot packet counts.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_rx_bytes_count = {}#
Next slot byte counts.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pcap_buffer = {}#
PCAP capture buffer.
-
std::array<std::uint8_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pcap_buffer_ts = {}#
PCAP timestamp buffer.
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> pcap_buffer_index = {}#
PCAP buffer index.
-
int *barrier_flag = {nullptr}#
Barrier flag for synchronization (Phase 2)
Completion flag (Phase 2)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_num_prb_ch1 = {}#
Next slot PRB count channel 1 (Phase 2)
-
std::array<std::uint32_t*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> next_slot_num_prb_ch2 = {}#
Next slot PRB count channel 2 (Phase 2)
-
std::array<doca_gpu_eth_rxq*, ORDER_KERNEL_MAX_CELLS_PER_SLOT> rxq_info_gpu = {}#
-
struct PacketSendTimeParams#
- #include <fronthaul.hpp>
Packet send time calculation input parameters
Public Members
-
std::chrono::nanoseconds t0 = {}#
Time for system frame 0, subframe 0, slot 0.
-
std::chrono::nanoseconds tai_offset = {}#
TAI offset for time synchronization.
-
std::uint64_t absolute_slot = {}#
Absolute slot number being processed.
-
std::chrono::nanoseconds slot_period = {}#
Slot period.
-
std::uint32_t slot_ahead = {}#
Number of slots processing is ahead of real-time.
-
std::chrono::nanoseconds t1a_max_cp_ul = {}#
T1a max window for uplink C-plane.
-
std::chrono::nanoseconds actual_start = {}#
Actual processing start time (current time)
-
std::chrono::nanoseconds t0 = {}#
-
struct PacketSendTimeResult#
- #include <fronthaul.hpp>
Packet send time calculation result
Public Members
-
std::chrono::nanoseconds expected_start = {}#
Expected slot start time.
-
std::chrono::nanoseconds actual_start = {}#
Actual processing start time.
-
std::chrono::nanoseconds time_delta = {}#
Delta between actual and expected.
-
std::chrono::nanoseconds threshold = {}#
Timing threshold.
-
std::chrono::nanoseconds start_tx = {}#
Calculated packet transmission time.
-
bool exceeds_threshold = {}#
True if delta exceeds threshold.
-
std::chrono::nanoseconds expected_start = {}#
-
struct UPlaneConfig#
- #include <uplane_config.hpp>
U-Plane configuration parameters
Configuration for ORAN U-Plane packet reception using Order Kernel pipeline. Default values are suitable for 30kHz SCS (500us slot duration) in production environments.
Public Members
-
std::uint64_t ta4_min_ns = {50'000}#
Ta4 early window (50us before slot start)
-
std::uint64_t ta4_max_ns = {450'000}#
Ta4 late window (450us after slot start)
-
std::uint64_t slot_duration_ns = {500'000}#
Slot duration (500us for 30kHz SCS)
-
std::uint64_t timeout_no_pkt_ns = {DEFAULT_TIMEOUT_NO_PKT_NS}#
Timeout with no packets (default: 6s)
-
std::uint64_t timeout_first_pkt_ns = {DEFAULT_TIMEOUT_FIRST_PKT_NS}#
Timeout for first packet (default: 1500us)
-
std::uint64_t timeout_log_interval_ns = {DEFAULT_TIMEOUT_LOG_INTERVAL_NS}#
Timeout log interval (default: 1s)
-
bool timeout_log_enable = {true}#
Enable timeout logging.
-
std::uint32_t max_rx_pkts = {DEFAULT_MAX_RX_PKTS}#
Maximum RX packets to process per iteration (default: 512)
-
std::uint64_t rx_pkts_timeout_ns = {DEFAULT_RX_PKTS_TIMEOUT_NS}#
RX packet timeout (default: 100us)
-
std::uint32_t num_packets = {16384}#
Number of packet buffers in RX queue (16K)
-
std::uint32_t max_packet_size = {8192}#
Maximum packet size (8KB, observed 1494 bytes in production)
-
std::uint32_t gpu_semaphore_items = {4096}#
GPU semaphore items (4096, must be power of 2)
-
std::vector<std::uint16_t> eaxc_ids = {0, 1, 2, 3}#
UL eAxC IDs for antenna ports (default: [0, 1, 2, 3])
-
std::uint64_t ta4_min_ns = {50'000}#