Cellular Emitter Algorithms

5G NR, LTE, and GSM waveform-synthesis design material. NRPuschEmitter is a fully implemented, currently supported rfgen generation path (§8.1 below); LTEEmitter is still a stub, and the GSM material (§8.3) remains illustrative pseudocode rather than a runnable API. See the Emitter API and Signal Catalog for current availability.

8. Cellular

8.1 5G NR PUSCH via sionna.phy.nr

NRPuschEmitter (rfgen.domains.comms.cellular) delegates all 5G NR uplink PHY work to sionna.phy.nr.PUSCHTransmitter/PUSCHConfig: resource-grid mapping, DMRS insertion, transport-block encoding (LDPC + rate matching), scrambling, and OFDM modulation are all performed by Sionna’s own NR module, which independently implements 3GPP TS 38.211/38.212. No NR PHY logic is reimplemented in rfgen. See the Emitter API for the full NRPuschParams schema (resource-block count, MCS index, subcarrier spacing, and an optional bandwidth override) and the Phase-2 physics validation for the conformance evidence (a real DMRS at OFDM symbol index 2 and a real, correctly sized transport block).

Sionna generates one uplink slot at a time at its own native sample rate; NRPuschEmitter.generate() transmits as many consecutive slots as needed to cover the requested duration, concatenates them, and resamples onto the caller’s requested sample rate with scipy.signal.resample_poly. PDSCH, SSB, PRACH, CSI-RS, and NR test-model emitters remain outside this emitter’s scope.

8.2 Proposed LTE route via srsRAN_4G ZMQ

srsRAN_4G is AGPL-3.0 and is not bundled. LTEEmitter is currently a stub; the following is design material, not an opt-in runnable workflow.

def generate_lte(*, class_label, sample_rate, duration_s, params, rng):
    """
    class_label: "cellular.lte.fdd.bw-{1.4,3,5,10,15,20}mhz"
    params:
        bandwidth_mhz: float
        cell_id: int
        pdsch_payload: "random" | bytes
    """
    bw_to_rb = {1.4: 6, 3: 15, 5: 25, 10: 50, 15: 75, 20: 100}
    n_rb = bw_to_rb[params["bandwidth_mhz"]]

    # Spawn srsenb subprocess writing IQ to a ZMQ socket; we read from the socket.
    handle = _spawn_srsran(
        config_template="lte_dl.conf.j2",
        n_prb=n_rb,
        cell_id=params["cell_id"],
        zmq_tx_port=_pick_free_port(),
        seed=int(rng.initial_seed()),
    )
    iq_native = _read_zmq_for(duration_s + 0.1, handle)  # buffer extra
    handle.terminate()
    iq = _resample(iq_native, native_rate=30.72e6, target_rate=sample_rate)
    iq = _trim_or_pad(iq, target_len=int(round(sample_rate * duration_s)))
    return Signal(iq=iq, metadata=SignalMetadata(bandwidth_hz=params["bandwidth_mhz"] * 1e6, ...))

Verification. Round-trip a known transport block through srsRAN_4G TX + a separate srsRAN_4G or open-source LTE RX.

8.3 GSM GMSK design note

Potential pure-NumPy GMSK at 270.833 kbit/s (legacy completeness only); no supported rfgen GSM emitter is documented by this sketch.

def generate_gsm(*, class_label, sample_rate, duration_s, params, rng):
    """class_label = "cellular.gsm.gmsk-200khz" """
    bit_rate = 270833.0
    bt = 0.3  # GSM uses BT = 0.3
    bw = 200e3
    bits = _gsm_burst_bitstream(rng)  # normal burst: 3 tail + 58 data + 26 training + 58 data + 3 tail + 8.25 guard
    return _gmsk_modulate(bits, bit_rate, bt, sample_rate, duration_s)

GMSK reuses the BLE GFSK algorithm (§4) with BT = 0.3, h = 0.5.


See Also

References

Items 1-3 and 7 describe the standard and library NRPuschEmitter (§8.1) delegates to today. The remaining sources (srsRAN_4G and the GSM specifications) describe potential upstream implementations for the still-stub LTEEmitter (§8.2) and the illustrative GSM sketch (§8.3); they do not establish a current rfgen waveform-generation capability for those two.

  1. 3GPP TS 38.211, NR; Physical channels and modulation (Release 18). 3rd Generation Partnership Project, 2024. (PUSCH subcarrier spacing, n_size_grid, OFDM numerology used by sionna.phy.nr)

  2. 3GPP TS 38.212, NR; Multiplexing and channel coding (Release 18). 3GPP, 2024. (Transport block MCS table referenced by pusch_config.tb.mcs_table)

  3. 3GPP TS 38.214, NR; Physical layer procedures for data (Release 18). 3GPP, 2024. (PUSCH MCS-to-modulation mapping for QPSK / 16-QAM / 64-QAM / 256-QAM)

  4. 3GPP TS 36.211, E-UTRA; Physical channels and modulation (Release 17). 3GPP, 2023. (LTE PRB count vs. channel bandwidth; 30.72 MHz native sample rate at 20 MHz)

  5. 3GPP TS 45.004, GSM/EDGE; Modulation. 3GPP, 2020. (GSM GMSK at 270.833 kbit/s, BT = 0.3 Gaussian filter, h = 0.5 modulation index)

  6. 3GPP TS 45.002, GSM/EDGE; Multiplexing and multiple access on the radio path. 3GPP, 2020. (Normal burst structure: 3 + 58 + 26 + 58 + 3 + 8.25 guard symbols)

  7. Hoydis, J. et al. Sionna: An Open-Source Library for Next-Generation Physical Layer Research, NVIDIA, 2022. https://nvlabs.github.io/sionna/. (sionna.phy.nr PUSCHTransmitter API and validation against 3GPP test models)

  8. srsRAN Project. srsRAN_4G: Open-source 4G/5G software radio suite. https://github.com/srsran/srsRAN_4G. (AGPL-3.0 LTE stack used for the LTE path)