Upper PHY (DU-Low) architecture

How OCUDU implements the Upper PHY (DU-Low) — downlink and uplink processing chains, channel coding (LDPC, polar), modulation, channel estimation, DFT backends, resource grid, hardware acceleration integration, and concurrency model.

Target audience: RAN engineers. Scope: the Upper PHY (DU-Low) implementation in OCUDU under lib/phy/upper/ and lib/phy/generic_functions/ — class ownership, DL and UL processing chains, channel coding (LDPC, polar, CRC), modulation and demodulation, channel estimation, DFT backends, resource grid and buffer management, hardware acceleration hooks, and concurrency model. Lower PHY (OFDM, front-end IQ) and OFH/eCPRI transport are separate compilation units and out of scope here.


1. What the Upper PHY Does

The Upper PHY (also called DU-Low in O-RAN terminology) implements all symbol-level baseband processing that sits between the MAC scheduler and the radio unit. On the downlink it takes transport blocks and control words from the MAC/scheduler and outputs a modulated, precoded resource grid ready for the RU to transmit. On the uplink it accepts time-domain samples from the RU, demodulates them, decodes LDPC or polar-coded payloads, and delivers soft decisions and decoded bits to the MAC.


2. Top-Level Architecture

upper_phy_impl

File: lib/phy/upper/upper_phy_impl.h/.cpp

upper_phy_impl
├── dl_rg_pool           resource_grid_pool        Pre-allocated DL resource grids
├── dl_processor_pool    downlink_processor_pool   One processor per SCS x slot-round-robin
├── ul_processor_pool    uplink_processor_pool     Circular array of 16 UL processors
├── rx_buf_pool          rx_buffer_pool_controller Soft-bit HARQ buffers per UE per HARQ ID
├── ul_request_processor uplink_request_processor_impl  UL slot/PRACH entry point
├── rx_results_notifier  upper_phy_rx_results_notifier_wrapper  Callback to DU-Low
├── rx_symbol_handler    upper_phy_rx_symbol_handler    Symbol capture from RU
├── dl_pdu_validator     downlink_pdu_validator
├── ul_pdu_validator     uplink_pdu_validator
├── timing_handler       upper_phy_timing_handler_impl
└── error_handler        upper_phy_error_handler_impl

3.1 Processor Pool and Dispatch

downlink_processor_pool_impl (lib/phy/upper/downlink_processor_pool_impl.h) groups processors by SCS. The MAC selects a processor for a given slot with:

unique_downlink_processor dp =
    pool.get_processor_controller(slot)
        .configure_resource_grid(context, shared_resource_grid);

This returns an RAII unique_downlink_processor. When that object is destroyed (end of slot), finish_processing_pdus() fires and the fully assembled resource grid is sent to the RU gateway.

File: lib/phy/upper/downlink_processor_multi_executor_impl.h/.cpp

Each PDU type (PDCCH, PDSCH, SSB, CSI-RS, PRS) has a dedicated task_executor. PDU processing tasks are enqueued asynchronously; a downlink_processor_multi_executor_state counter tracks pending tasks. When the pending count reaches zero and the finish flag is set, the grid is sent.

This design means PDCCH and PDSCH tasks can run on different CPU cores in parallel for the same slot.

3.3 PDSCH Processor

File: lib/phy/upper/channel_processors/pdsch/pdsch_processor_impl.h/.cpp

pdsch_processor_impl
├── pdsch_encoder     → segmentation → CRC → LDPC encode → rate match → scramble
├── pdsch_modulator   → QAM map → layer map → precoding → RE mapping
├── dmrs_pdsch_processor  → DM-RS sequence generation and insertion
└── ptrs_pdsch_generator  → PT-RS (optional)

Processing steps:

  1. Segmentation — transport block split into codeblocks per TS 38.212 Section 5.2.2; 24-bit CB CRC added if more than one CB.
  2. LDPC encoding — BG1 or BG2 selected by CB size; lifting size selected from eight options up to 384; high-rate parity bits computed first, extended parity optional.
  3. Rate matching — circular buffer model (TS 38.212 Section 5.4.2.1); puncture or repeat bits to reach target coded size E.
  4. Scrambling — Gold sequence XOR keyed by cell ID and RNTI (TS 38.211 Section 5.2.1).
  5. QAM modulation — QPSK, 16-QAM, 64-QAM, or 256-QAM via LUT or SIMD mapper.
  6. Layer mapping — up to 4 spatial layers.
  7. Precoding and resource mappingresource_grid_mapper writes complex symbols into the DL resource grid at the correct subcarrier, OFDM symbol, and antenna port positions.
  8. DM-RS insertion — pseudo-random (Gold) sequence keyed by cell ID and PDSCH RNTI, pattern by CDM group and density (TS 38.211 Section 7.4.1.1).
  9. PT-RS insertion — phase tracking reference signals (optional, depends on UE configuration).

pdsch_processor_notifier.on_finish_processing() is called when the grid contribution is complete.

3.4 PDCCH Processor

File: lib/phy/upper/channel_processors/pdcch/pdcch_processor_impl.h/.cpp

pdcch_processor_impl
├── pdcch_encoder   → DCI bits → polar code → scramble
├── pdcch_modulator → QPSK → CORESET RE mapping
└── dmrs_pdcch_processor → DM-RS (Gold, keyed by cell ID + CORESET index)

Polar encoding covers variable-length DCI payloads (up to 164 bits per TS 38.212 Section 5.1). QPSK is the only modulation for PDCCH. RE mapping follows the aggregation level: 1, 2, 4, 8, or 16 CCEs within the CORESET (TS 38.213 Section 8.1.1).

3.5 SSB Processor

File: lib/phy/upper/channel_processors/ssb/ssb_processor_impl.h/.cpp

ssb_processor_impl
├── pss_processor  → Zadoff-Chu sequence (root u = cell_id mod 3, length 127)
├── sss_processor  → Gold sequence (cell_id mod 168, frame number, length 127)
├── pbch_encoder   → 24-bit MIB + 8-bit control → polar code (N=32)
├── pbch_modulator → QPSK + layer mapping
└── dmrs_pbch_processor → DM-RS (Gold, keyed by cell ID)

The SS/PBCH block occupies 4 OFDM symbols x 20 PRBs (240 REs). The RE pattern for PSS, SSS, PBCH, and DM-RS positions is fixed by numerology and frequency range.

3.6 NZP-CSI-RS Generator

File: lib/phy/upper/signal_processors/nzp_csi_rs/nzp_csi_rs_generator_impl.h/.cpp

Generates non-zero-power CSI-RS according to a configurable density, periodicity, and port count. Sequence is Gold, keyed by cell ID and CSI-RS port index (TS 38.211 Section 7.4.1.5). RE pattern depends on resource_config (density, time/frequency offset).

3.7 PRS Generator

File: lib/phy/upper/signal_processors/prs/prs_generator_impl.h

Positioning Reference Signal. Gold sequence keyed by cell ID and PRS resource ID. RE pattern configurable per SCS, density, and periodicity. Generated as part of the downlink PDU pipeline.


4.1 Processor Pool and Dispatch

uplink_processor_pool_impl (lib/phy/upper/uplink_processor_pool_impl.h) maintains a circular array of 16 uplink_processor_impl instances. Assignment is round-robin by slot. A default processor handles unassigned PRACH and symbol requests.

File: lib/phy/upper/uplink_processor_impl.h/.cpp

uplink_processor_impl
├── prach_detector      → frequency-domain preamble detection
├── pusch_processor     → DM-RS estimation → equalization → demod → decode
├── pucch_processor     → per-format detection or demod + decode
├── srs_estimator       → SRS channel estimation
├── ul_grid             → local RX resource grid for this UL slot
└── uplink_processor_fsm → state machine (EMPTY → STORING_SYMBOLS → PROCESSING → IDLE)

The FSM accumulates symbols as they arrive from the RU (process_ul_signal()), one OFDM symbol at a time. When the slot boundary is reached, it triggers PUSCH, PUCCH, and SRS processing.

4.3 PUSCH Processor

File: lib/phy/upper/channel_processors/pusch/pusch_processor_impl.h/.cpp

PUSCH processing is event-driven, not slot-synchronous. The DM-RS estimator runs in an executor pool; when it completes, a notifier callback triggers the demodulator and decoder.

sequenceDiagram
    participant FSM as uplink_processor_fsm
    participant PUSCH as pusch_processor_impl
    participant EST as dmrs_pusch_estimator
    participant DEMOD as pusch_demodulator
    participant DEC as pusch_decoder
    participant UCI as uci_decoder

    FSM->>PUSCH: process(grid, rx_buffer, pdu)
    PUSCH->>EST: estimate(notifier, grid, config) [async in executor]
    EST-->>PUSCH: on_estimation_complete(channel_estimates, noise_variance)
    PUSCH->>DEMOD: demodulate(grid, channel_estimates, noise_variance)
    PUSCH->>DEC: decode_sch(soft_bits, rx_buffer)
    PUSCH->>UCI: decode HARQ-ACK / CSI Part 1 / CSI Part 2
    PUSCH->>MAC: on_new_pusch_results_data(decoded_bits, crc, csi)

Processing steps:

  1. DM-RS extraction and channel estimation — per RX port, in parallel (executor pool). Computes channel frequency response at pilot subcarriers; interpolates across data subcarriers and OFDM symbols. Estimates noise variance from pilot residuals.
  2. Equalization — ZF or MMSE per subcarrier, using the estimated channel and noise variance.
  3. Soft-bit demodulation (LLR computation) — approximate log-likelihood ratio per bit: LLR(b_i) ≈ -1/σ² × [min_{S_{i,0}} |y-s|² - min_{S_{i,1}} |y-s|²].
  4. Rate de-matching — maps received LLRs back to encoder output positions; unmatched positions zero-filled.
  5. LDPC decoding — layered belief propagation with min-sum approximation; up to configured max iterations; early stop on syndrome pass.
  6. UCI extraction — HARQ-ACK, CSI Part 1, CSI Part 2 extracted from reserved REs or multiplexed in payload; decoded via separate uci_decoder instances.

concurrent_dependencies (estimator + demodulator + UCI decoder set) is acquired from concurrent_dependencies_pool_type per PDU. Multiple PUSCH PDUs in the same slot can run concurrently.

unique_rx_buffer holds the soft-bit HARQ buffer from rx_buffer_pool_controller. For a HARQ retransmission, the pool returns the same buffer so that the decoder can combine LLRs across retransmissions. Buffers expire after a configurable number of slots.

4.4 PUCCH Processor

File: lib/phy/upper/channel_processors/pucch/pucch_processor_impl.h

Handles four formats; each is a separate processing path:

FormatPayloadMethod
Format 01-2 HARQ-ACK bitsNC-PSK correlation (single RB, 1 symbol)
Format 11-2 HARQ-ACK + SRCorrelation on 2 OFDM symbols with intra-slot hopping
Format 2Up to 3 bitsPolar code + QPSK on 1 RB x 1 symbol
Format 3, 4Up to 11 bitsLDPC or polar code on multiple RBs and symbols

All formats begin with DM-RS-based channel estimation followed by ZF or MMSE equalization.

4.5 PRACH Detector

File: lib/phy/upper/channel_processors/prach/prach_detector_generic_impl.h/.cpp

For each preamble index, the detector:

  1. Generates the expected Zadoff-Chu sequence in frequency domain.
  2. Computes cross-correlation with the captured PRACH window (via IDFT).
  3. Estimates noise power from the correlation output.
  4. Computes the generalized log-likelihood ratio: |correlation|² / noise_power.
  5. Thresholds and returns detected preambles with timing advance (sample offset from correlation peak).

Long preambles use a 4096-point IDFT; short preambles use a 2048-point IDFT. Both use the configurable DFT backend (see Section 8).


5. Channel Coding

5.1 LDPC Encoder

File: lib/phy/upper/channel_coding/ldpc/ldpc_encoder_impl.h/.cpp

Template method pattern: ldpc_encoder_impl defines the algorithm structure; concrete subclasses provide SIMD kernels.

SIMD variants:

  • ldpc_encoder_avx2.cpp — 256-bit operations.
  • ldpc_encoder_neon.cpp — ARM 128-bit.
  • ldpc_encoder_generic.cpp — scalar fallback.

Base graphs (TS 38.212 Section 5.3.2):

  • BG1: 22 information columns, 68 full columns, 46 check equations (longer codeblocks).
  • BG2: 22 information columns, 52 full columns, 42 check equations (shorter codeblocks).

Lifting sizes: 8 sets (up to 384) per TS 38.212. Actual codeblock size = K x lifting_size.

The encoder writes only the high-rate parity region (first 4 x lifting_size parity bits) by default. Extended parity is computed on demand for rate matching that requires a larger circular buffer.

5.2 LDPC Graph

File: lib/phy/upper/channel_coding/ldpc/ldpc_graph_impl.h/.cpp

Stores the parity-check matrix as static lookup tables for all 16 (base graph x lifting set) combinations. Each entry is a circular shift amount or NO_EDGE (0xffff). The decoder uses ldpc_graph_impl to know which variable nodes are connected to each check node, and what shift to apply.

5.3 LDPC Decoder

File: lib/phy/upper/channel_coding/ldpc/ldpc_decoder_impl.h/.cpp

Algorithm: Layered Belief Propagation with Min-Sum Approximation

SIMD variants:

  • ldpc_decoder_avx2.cpp
  • ldpc_decoder_avx512.cpp
  • ldpc_decoder_neon.cpp
  • ldpc_decoder_generic.cpp

One iteration per check-node layer in the base graph:

  1. Compute variable-to-check (V2C) messages from current soft bits.
  2. Find the two minimum absolute V2C values and the sign product for each lifted group.
  3. Compute check-to-variable (C2V) messages: C2V = sign_product × min(|V2C|, second_min) × 0.8.
  4. Update soft bits: soft_bits += C2V_new - C2V_old.

Scaling factor 0.8 is the standard min-sum correction. Soft bits are clamped to [-64, +64]. Iteration continues until the CRC matches, the syndrome is satisfied (if early_stop_syndrome is set), or max iterations is reached.

5.4 Rate Matcher

File: lib/phy/upper/channel_coding/ldpc/ldpc_rate_matcher_impl.h/.cpp

Implements the circular buffer model from TS 38.212 Section 5.4.2.1. The encoder output is treated as a circular sequence; starting from the extended parity region, exactly E bits are selected by circular traversal — puncturing (skipping) or repeating as needed. SIMD variants (AVX2, AVX512, NEON) vectorize the scatter/gather operations.

The rate de-matcher (RX side) maps received LLRs back to encoder-output positions and fills unmatched positions with 0.

5.5 Segmenter

TX segmenter (ldpc_segmenter_tx_impl): splits a transport block into codeblocks of equal size per TS 38.212 Section 5.2.2. Adds a 24-bit CRC to each codeblock if more than one codeblock is produced.

RX segmenter (ldpc_segmenter_rx_impl): reassembles decoded codeblocks, verifies per-CB CRC, and returns the transport block. If any CB CRC fails, the TB is flagged as NACK.

5.6 Polar Encoder / Decoder

Files: lib/phy/upper/channel_coding/polar/

Used for PDCCH (DCI) and PBCH (MIB). The decoder uses Successive Cancellation (SC) or SC-List (SCL) with CRC-aided early termination.

5.7 CRC Calculator

Four implementations selected at factory time:

VariantFile suffixMethod
LUT_lut_impl256-entry lookup table
CLMUL_clmul_implx86 SSE4.2 carryless multiply
NEON_neon_implARM NEON
Generic_generic_implScalar bit-by-bit

Polynomials: CRC-24A (0x864CFB), CRC-24B (0x800063), CRC-8 (0x9B) per TS 38.212 Section 5.1.1.


6. Modulation

6.1 Modulation Mapper

File: lib/phy/upper/channel_modulation/modulation_mapper_lut_impl.h/.cpp

Supports QPSK, 16-QAM, 64-QAM, 256-QAM. Output is unit-average-power complex symbols. LUT variant pre-computes all constellation points; SIMD variants vectorize the lookup.

SIMD variants:

  • modulation_mapper_avx512_impl — 16 symbols per SIMD operation.
  • modulation_mapper_neon_impl — 4-8 symbols per SIMD operation.

6.2 Demodulation Mapper (Soft-Bit Extraction)

File: lib/phy/upper/channel_modulation/demodulation_mapper_impl.h/.cpp

Computes approximate LLRs using the nearest-neighbour minimum-distance formula:

LLR(b_i) = -1/σ² × [ min_{s in S_{i,0}} |y - s|²  -  min_{s in S_{i,1}} |y - s|² ]

QAM-specific files (_qpsk, _qam16, _qam64, _qam256) pre-compute I/Q quadrant lookup tables for the minimum-distance search. LLR values are represented as log_likelihood_ratio (int8 or float32 depending on the path).


7. Channel Estimation

7.1 Port Channel Estimator

File: lib/phy/upper/signal_processors/channel_estimator/port_channel_estimator_average_impl.h/.cpp

Per-port, per-OFDM-symbol estimation:

  1. Extract DM-RS symbols from pilot RE positions.
  2. Least-squares channel estimate at pilot subcarriers.
  3. Frequency-domain interpolation across data subcarriers.
  4. Time-domain interpolation (if multiple DM-RS symbols exist in the slot).
  5. Noise variance estimated from pilot residuals.

7.2 PUSCH Channel Estimator

File: lib/phy/upper/signal_processors/pusch/dmrs_pusch_estimator_impl.h

Spawns one port_channel_estimator task per RX port in an executor pool. Aggregates results and fires dmrs_pusch_estimator_notifier.on_estimation_complete() when all ports are done.

DM-RS sequences:

  • Type 1: 1 DM-RS OFDM symbol per slot.
  • Type 2: 2 DM-RS OFDM symbols per slot.
  • Pseudo-random (Gold) seeded by cell ID + UE ID.
  • Optional low-PAPR sequences for transform-precoded PUSCH.

7.3 PUCCH Channel Estimator

Format-specific estimators:

  • dmrs_pucch_estimator_format2.cpp — 1 symbol, single RB.
  • dmrs_pucch_estimator_formats3_4.cpp — multiple symbols and RBs.

8. DFT / FFT Backends

Interface: include/ocudu/phy/generic_functions/dft_processor.h
dft_processor::run() performs in-place DFT/IDFT on a pre-allocated input buffer.

BackendFileNotes
FFTWdft_processor_fftw_implUses fftwf_plan; configurable ESTIMATE/MEASURE/EXHAUSTIVE; optional wisdom file
AMD AOCL (FFTZ)dft_processor_fftz_implAMD FFTPACK wrapper; similar API
AVX2 CI16dft_processor_ci16_avx2Integer I/Q (int16); Cooley-Tukey radix-4 with AVX2 butterflies; used for small sizes
Genericdft_processor_generic_implScalar radix-2/4 fallback

The factory in lib/phy/generic_functions/generic_functions_factories.cpp selects the backend. FFTW and FFTZ are compile-time options (ENABLE_FFTW, ENABLE_FFTZ). PRACH detection uses IDFT through this interface.


9. Resource Grid and Buffers

9.1 Resource Grid

File: lib/phy/support/resource_grid_impl.h/.cpp

A 3D tensor [subcarrier x OFDM_symbol x antenna_port] stored as cbf16_t (complex block float-16, reduced memory footprint vs float32). resource_grid_writer and resource_grid_reader provide the DL and UL views.

shared_resource_grid wraps the grid in a shared_ptr + pool notifier for automatic return on scope exit.

Pool (resource_grid_pool_impl): maintains N pre-allocated grids; allocate_resource_grid(slot) returns a round-robin grid. On release, the grid is async-zeroed if an executor is available.

9.2 RX Buffer Pool

File: lib/phy/upper/rx_buffer_pool_impl.h/.cpp

rx_buffer_pool_impl
├── rx_buffer_codeblock_pool     shared pool of soft-bit CB buffers
├── rx_buffer_impl[]             per (UE, HARQ process) buffers
├── trx_buffer_identifier[]      identity: (RNTI, HARQ ID)
└── slot_point expiration[]      buffer released after N slots

reserve(slot, id, nof_codeblocks, new_data) returns unique_rx_buffer. If new_data=false (retransmission), the same buffer is returned so LLRs combine across transmissions. Expired buffers are reclaimed automatically.


10. Sequence Generators

10.1 Gold Sequence (Pseudo-Random)

File: lib/phy/upper/sequence_generators/pseudo_random_generator_impl.h

Two LFSR registers x1 and x2 per TS 38.211 Section 5.2.1. Output: c[n] = (x1[n] + x2[n]) mod 2. c_init encodes cell ID, RNTI, or other context. The implementation uses bit-parallel LFSR (32 bits per cycle) and supports fast-advance via state transition matrices.

Used in: PDCCH DM-RS, PDSCH DM-RS, PBCH DM-RS, NZP-CSI-RS, PSS, PRS, scrambling.

10.2 Low-PAPR (Zadoff-Chu / Cyclic-Shifted)

File: lib/phy/upper/sequence_generators/low_papr_sequence_generator_impl.h

Zadoff-Chu: u[k] = exp(-j pi u k(k+1) / N) for root u and length N. Used in PRACH preamble generation and transform-precoded PUSCH (DFT-s-OFDM).


11. Hardware Acceleration Integration

Two *_hw_impl classes exist as drop-in replacements for SW implementations:

  • pdsch_encoder_hw_impl (lib/phy/upper/channel_processors/pdsch/) — wraps hal_ldpc_encoder.
  • pusch_decoder_hw_impl (lib/phy/upper/channel_processors/pusch/) — wraps hal_ldpc_decoder.

The HAL interface (include/ocudu/hal/hw_accelerator.h) is the abstraction layer for accelerator devices (ACC100/ACC200/VRB1 in the implemented backend). Factory selection in lib/phy/upper/upper_phy_factories.cpp chooses between HW and SW based on build-time and runtime configuration. If hardware_encoder_available && use_hw_encoder, the HW variant is instantiated; otherwise the AVX2 or generic SW path is used.

Modulation and DFT remain on the CPU even when LDPC is offloaded. See the Hardware Acceleration section for HAL and BBDev details.


12. Concurrency Model

Each DL PDU type runs on a dedicated task_executor:

process_pdcch(pdu) → enqueue on pdcch_executor
process_pdsch(pdu) → enqueue on pdsch_executor
process_ssb(pdu)   → enqueue on ssb_executor
process_nzp_csi_rs → enqueue on csi_rs_executor

A counter tracks pending tasks. The resource grid is sent to the RU only when pending_pdus == 0 && should_finish. This provides per-channel parallelism within a slot without requiring locks on the resource grid (each channel type writes to non-overlapping RE positions).

Within PROCESSING, DM-RS estimation tasks run in an executor pool. Each PUSCH PDU acquires a concurrent_dependencies object (estimator + demodulator + UCI decoder). Multiple UEs’ PUSCH can be estimated in parallel; each individual decode sequence (demod → rate dematch → LDPC) is serial per PDU.


13. DU-Low Interface

unique_downlink_processor dp =
    upper_phy.get_downlink_processor_pool()
        .get_processor_controller(slot)
        .configure_resource_grid(context, grid);

dp.process_pdcch(pdcch_pdu);
dp.process_pdsch(transport_blocks, pdsch_pdu);
dp.process_ssb(ssb_pdu);
// dp destroyed here → finish_processing_pdus() called → grid sent to RU
upper_phy.get_uplink_request_processor().process_uplink_slot_request(context, grid);
upper_phy.get_uplink_request_processor().process_prach_request(prach_context);

Result Callbacks (Upper PHY → DU-Low)

notifier.on_new_pusch_results_data({ rnti, slot, harq_id, decoder_result, payload, csi });
notifier.on_new_pucch_results({ rnti, slot, format, harq_ack, sr, csi });
notifier.on_new_prach_results({ rnti, slot, time_advance });

All results are delivered via upper_phy_rx_results_notifier_wrapper which forwards to the DU-High MAC.


14. 3GPP References in Code

StandardClauseCoverage
TS 38.211Section 5.2.1Gold sequence generation
TS 38.211Section 7.4.1.1PDSCH DM-RS RE patterns
TS 38.211Section 7.4.1.5NZP-CSI-RS patterns
TS 38.211Section 7.3.1PDSCH resource mapping
TS 38.211Section 7.3.2PDCCH resource mapping
TS 38.211Section 6.3.3.1PRACH preamble format
TS 38.212Section 5.1Polar coding
TS 38.212Section 5.2.2LDPC segmentation
TS 38.212Section 5.3.1Polar code construction
TS 38.212Section 5.3.2LDPC base graphs BG1 / BG2
TS 38.212Section 5.4.2.1LDPC rate matching (circular buffer)
TS 38.213Section 8.1.1PDCCH aggregation levels

15. File Reference Index

ComponentHeaderImplementation
Upper PHY orchestratorupper_phy_impl.hupper_phy_impl.cpp
DL processor pooldownlink_processor_pool_impl.hdownlink_processor_pool_impl.cpp
DL processordownlink_processor_multi_executor_impl.hdownlink_processor_multi_executor_impl.cpp
PDSCH processorpdsch_processor_impl.hpdsch_processor_impl.cpp
PDCCH processorpdcch_processor_impl.hpdcch_processor_impl.cpp
SSB processorssb_processor_impl.hssb_processor_impl.cpp
NZP-CSI-RS generatornzp_csi_rs_generator_impl.hnzp_csi_rs_generator_impl.cpp
UL processor pooluplink_processor_pool_impl.huplink_processor_pool_impl.cpp
UL processoruplink_processor_impl.huplink_processor_impl.cpp
PUSCH processorpusch_processor_impl.hpusch_processor_impl.cpp
PUCCH processorpucch_processor_impl.hpucch_processor_impl.cpp
PRACH detectorprach_detector_generic_impl.hprach_detector_generic_impl.cpp
LDPC encoderldpc_encoder_impl.hldpc_encoder_impl.cpp, _avx2.cpp, _neon.cpp
LDPC decoderldpc_decoder_impl.h_generic.cpp, _avx2.cpp, _avx512.cpp, _neon.cpp
LDPC graphldpc_graph_impl.hldpc_graph_impl.cpp
LDPC rate matcherldpc_rate_matcher_impl.hldpc_rate_matcher_impl.cpp
LDPC segmenter (TX)ldpc_segmenter_tx_impl.hldpc_segmenter_tx_impl.cpp
Polar encoderpolar_encoder_impl.hpolar_encoder_impl.cpp
Polar decoderpolar_decoder_impl.hpolar_decoder_impl.cpp
Modulation mapper (LUT)modulation_mapper_lut_impl.hmodulation_mapper_lut_impl.cpp
Modulation mapper (AVX512)modulation_mapper_avx512_impl.hmodulation_mapper_avx512_impl.cpp
Demodulation mapperdemodulation_mapper_impl.hdemodulation_mapper_impl.cpp
Port channel estimatorport_channel_estimator_average_impl.hport_channel_estimator_average_impl.cpp
PUSCH channel estimatordmrs_pusch_estimator_impl.hdmrs_pusch_estimator_impl.cpp
PDSCH DM-RSdmrs_pdsch_processor_impl.hdmrs_pdsch_processor_impl.cpp
PDCCH DM-RSdmrs_pdcch_processor_impl.hdmrs_pdcch_processor_impl.cpp
PBCH DM-RSdmrs_pbch_processor_impl.hdmrs_pbch_processor_impl.cpp
PSS generatorpss_processor_impl.hpss_processor_impl.cpp
SSS generatorsss_processor_impl.hsss_processor_impl.cpp
Gold sequence generatorpseudo_random_generator_impl.hpseudo_random_generator_impl.cpp
DFT (FFTW)dft_processor_fftw_impl.hdft_processor_fftw_impl.cpp
DFT (FFTZ)dft_processor_fftz_impl.hdft_processor_fftz_impl.cpp
DFT (AVX2 CI16)dft_processor_ci16_avx2.hdft_processor_ci16_avx2.cpp
Resource gridresource_grid_impl.hresource_grid_impl.cpp
Resource grid poolresource_grid_pool_impl.hresource_grid_pool_impl.cpp
RX buffer poolrx_buffer_pool_impl.hrx_buffer_pool_impl.cpp
CRC calculatorcrc_calculator_*.hcrc_calculator_lut_impl.cpp, _clmul_impl.cpp, _neon_impl.cpp
PDSCH encoder HWpdsch_encoder_hw_impl.hpdsch_encoder_hw_impl.cpp
PUSCH decoder HWpusch_decoder_hw_impl.hpusch_decoder_hw_impl.cpp