Sionna
  • Installation
    • Using pip
    • From source
    • Testing
    • Documentation
    • Developing
  • Ray Tracing (RT)
    • Tutorials
      • Introduction to Sionna RT
        • Imports
        • Loading and Visualizing Scenes
        • Inspecting SceneObjects and Editing of Scenes
        • Ray tracing of Propagation Paths
        • From Paths to Channel Impulse and Frequency Responses
        • Radio Maps
        • Summary
      • Tutorial on Mobility
        • Background Information
        • GPU Configuration and Imports
        • Controlling Position and Orientation of Scene Objects
        • Time Evolution of Channels Via Doppler Shift
          • Example: Delay-Doppler Spectrum
        • Comparison of Doppler- vs Position-based Time Evolution
        • Summary
      • Tutorial on Radio Maps
        • Imports
        • Understanding radio maps
          • Metrics
          • Multiple transmitters
          • User association
          • Sampling of random user positions
          • Directional antennas and precoding vectors
        • Radio map for a realistic scene
          • Channel impulse responses for random user locations
        • Conclusions
      • Tutorial on Scattering
        • Imports
        • Scattering Basics
        • Scattering Patterns
        • Validation Against the “Far”-Wall Approximation
        • Radio Maps With Scattering
        • Impact on Channel Impulse Response
        • Summary
        • References
      • Tutorial on Loading and Editing of Scenes
        • Imports
        • Loading Scenes and Merging Objects
        • Editing Scenes
        • Path Computation with the Edited Scene
        • Summary
    • Primer on Electromagnetics
      • Coordinate system, rotations, and vector fields
      • Planar Time-Harmonic Waves
      • Far Field of a Transmitting Antenna
      • Modelling of a Receiving Antenna
      • General Propagation Path
      • Frequency & Impulse Response
      • Reflection and Refraction
        • Single-layer Slab
      • Diffraction
      • Scattering
      • Reconfigurable Intelligent Surfaces (RIS)
    • API Documentation
      • Antenna Arrays
        • AntennaArray
          • AntennaArray.antenna_pattern
          • AntennaArray.array_size
          • AntennaArray.normalized_positions
          • AntennaArray.num_ant
          • AntennaArray.positions()
          • AntennaArray.rotate()
        • PlanarArray
          • PlanarArray.antenna_pattern
          • PlanarArray.array_size
          • PlanarArray.normalized_positions
          • PlanarArray.num_ant
          • PlanarArray.positions()
          • PlanarArray.rotate()
          • PlanarArray.show()
      • Antenna Patterns
        • AntennaPattern
          • AntennaPattern.compute_gain()
          • AntennaPattern.patterns
          • AntennaPattern.show()
        • PolarizedAntennaPattern
          • PolarizedAntennaPattern.compute_gain()
          • PolarizedAntennaPattern.patterns
          • PolarizedAntennaPattern.show()
        • Vertically Polarized Antenna Pattern Functions
          • v_iso_pattern()
          • v_dipole_pattern()
          • v_hw_dipole_pattern()
          • v_tr38901_pattern()
        • Polarization Models
          • polarization_model_tr38901_1()
          • polarization_model_tr38901_2()
        • Utility Functions
          • antenna_pattern_to_world_implicit()
          • complex2real_antenna_pattern()
          • register_antenna_pattern()
          • register_polarization()
          • register_polarization_model()
      • Cameras
        • Camera
          • Camera.look_at()
          • Camera.orientation
          • Camera.position
      • Paths
        • Paths
          • Paths.a
          • Paths.cfr()
          • Paths.cir()
          • Paths.doppler
          • Paths.interactions
          • Paths.num_rx
          • Paths.num_tx
          • Paths.objects
          • Paths.phi_r
          • Paths.phi_t
          • Paths.primitives
          • Paths.rx_array
          • Paths.sources
          • Paths.synthetic_array
          • Paths.taps()
          • Paths.targets
          • Paths.tau
          • Paths.theta_r
          • Paths.theta_t
          • Paths.tx_array
          • Paths.valid
          • Paths.vertices
        • Constants
          • InteractionType
          • INVALID_SHAPE
          • INVALID_PRIMITIVE
      • Path Solvers
        • PathSolver
          • PathSolver.__call__()
          • PathSolver.loop_mode
      • Radio Devices
        • RadioDevice
          • RadioDevice.color
          • RadioDevice.display_radius
          • RadioDevice.look_at()
          • RadioDevice.name
          • RadioDevice.orientation
          • RadioDevice.position
          • RadioDevice.velocity
        • Receiver
        • Transmitter
          • Transmitter.power
          • Transmitter.power_dbm
      • Radio Map
        • RadioMap
          • RadioMap.cdf()
          • RadioMap.cell_centers
          • RadioMap.cell_size
          • RadioMap.center
          • RadioMap.num_cells
          • RadioMap.num_rx
          • RadioMap.num_tx
          • RadioMap.orientation
          • RadioMap.path_gain
          • RadioMap.rss
          • RadioMap.rx_cell_indices
          • RadioMap.sample_positions()
          • RadioMap.show()
          • RadioMap.show_association()
          • RadioMap.sinr
          • RadioMap.size
          • RadioMap.tx_association()
          • RadioMap.tx_cell_indices
      • Radio Map Solvers
        • RadioMapSolver
          • RadioMapSolver.__call__()
          • RadioMapSolver.loop_mode
      • Radio Materials
        • RadioMaterialBase
          • RadioMaterialBase.color
          • RadioMaterialBase.eval()
          • RadioMaterialBase.name
          • RadioMaterialBase.pdf()
          • RadioMaterialBase.sample()
          • RadioMaterialBase.scene
          • RadioMaterialBase.to_string()
          • RadioMaterialBase.traverse()
        • RadioMaterial
          • RadioMaterial.conductivity
          • RadioMaterial.frequency_update()
          • RadioMaterial.frequency_update_callback
          • RadioMaterial.relative_permittivity
          • RadioMaterial.scattering_coefficient
          • RadioMaterial.scattering_pattern
          • RadioMaterial.thickness
          • RadioMaterial.xpd_coefficient
        • ITURadioMaterial
          • ITURadioMaterial.itu_type
          • ITURadioMaterial.to_string()
        • HolderMaterial
          • HolderMaterial.radio_material
          • HolderMaterial.velocity
        • Scattering Patterns
          • ScatteringPattern
          • LambertianPattern
          • DirectivePattern
          • BackscatteringPattern
          • register_scattering_pattern()
      • Scenes
        • load_scene()
        • Scene
          • Scene.add()
          • Scene.all_set()
          • Scene.angular_frequency
          • Scene.bandwidth
          • Scene.edit()
          • Scene.frequency
          • Scene.get()
          • Scene.mi_scene
          • Scene.mi_scene_params
          • Scene.objects
          • Scene.paths_solver
          • Scene.preview()
          • Scene.radio_materials
          • Scene.receivers
          • Scene.remove()
          • Scene.render()
          • Scene.render_to_file()
          • Scene.rx_array
          • Scene.scene_geometry_updated()
          • Scene.sources()
          • Scene.targets()
          • Scene.temperature
          • Scene.thermal_noise_power
          • Scene.transmitters
          • Scene.tx_array
          • Scene.wavelength
        • Examples
          • box
          • box_one_screen
          • box_two_screens
          • double_reflector
          • etoile
          • floor_wall
          • florence
          • munich
          • simple_reflector
          • simple_street_canyon
          • simple_street_canyon_with_cars
          • simple_wedge
          • triple_reflector
      • Scene Objects
        • SceneObject
          • SceneObject.look_at()
          • SceneObject.mi_shape
          • SceneObject.name
          • SceneObject.object_id
          • SceneObject.orientation
          • SceneObject.position
          • SceneObject.radio_material
          • SceneObject.scaling
          • SceneObject.scene
          • SceneObject.velocity
      • Utility Functions
        • Complex-valued tensors
          • cpx_abs()
          • cpx_abs_square()
          • cpx_add()
          • cpx_convert()
          • cpx_div()
          • cpx_exp()
          • cpx_mul()
          • cpx_sqrt()
          • cpx_sub()
        • Electromagnetics
          • complex_relative_permittivity()
          • fresnel_reflection_coefficients_simplified()
          • itu_coefficients_single_layer_slab()
        • Geometry
          • phi_hat()
          • theta_hat()
          • r_hat()
          • theta_phi_from_unit_vec()
          • rotation_matrix()
        • Jones calculus
          • implicit_basis_vector()
          • jones_matrix_rotator()
          • jones_matrix_rotator_flip_forward()
          • to_world_jones_rotator()
          • jones_matrix_to_world_implicit()
          • jones_vec_dot()
        • Miscellaneous
          • complex_sqrt()
          • dbm_to_watt()
          • isclose()
          • log10()
          • sigmoid()
          • sinc()
          • subcarrier_frequencies()
          • watt_to_dbm()
        • Ray tracing
          • fibonacci_lattice()
          • spawn_ray_from_sources()
          • offset_p()
          • spawn_ray_towards()
          • spawn_ray_to()
    • Developer Guides
      • Compatibility with other Frameworks
        • Type conversions
        • Gradients
        • Training-Loop in PyTorch
      • Understanding the Paths Object
      • Custom Antenna Patterns
        • Gradient-based Optimization
      • Understanding Radio Materials
        • Modifying Parameters of Radio Materials
        • Calibrating Material Parameters Through Gradient Descent
        • Custom Radio Materials
          • Representation of Jones vector and Matrices
          • Implicit Basis
          • The Local Interaction Basis
          • Mandatory Subclass Methods
          • Implementation of a Simple Radio Material Model
          • A More Complex Material Model
      • Custom Scattering Patterns
        • Differentiable Parameters
    • Technical Report
  • Physical Layer (PHY)
    • Tutorials
      • Beginners
        • “Hello, world!”
        • Part 1: Getting Started with Sionna
          • Imports & Basics
          • A note on random number generation
          • Sionna Data-flow and Design Paradigms
          • Hello, Sionna!
          • Communication Systems as Sionna Blocks
          • Forward Error Correction (FEC)
          • Eager vs Graph Mode
          • Exercise
        • Part 2: Differentiable Communication Systems
          • Imports
          • Gradient Computation Through End-to-end Systems
          • Creating Custom Layers
          • Setting up Training Loops
        • Part 3: Advanced Link-level Simulations
          • Imports
          • OFDM Resource Grid and Stream Management
          • Antenna Arrays
          • Channel Model
          • Uplink Transmission in the Frequency Domain
        • Part 4: Toward Learned Receivers
          • Imports
          • Simulation Parameters
          • Implemention of an Advanced Neural Receiver
          • Training the Neural Receiver
          • Benchmarking the Neural Receiver
          • Conclusion
          • References
        • Basic MIMO Simulations
          • Table of Contents
          • Simple uncoded transmission
          • Extension to channel coding
        • Pulse-shaping Basics
          • Table of Contents
          • GPU Configuration and Imports
          • Pulse-shaping of a sequence of QAM symbols
          • Recovering the QAM symbols through matched filtering and downsampling
          • Investigating the ACLR
          • Windowing
        • Optical Channel with Lumped Amplification
          • Table of Contents
          • Setup
          • Impulse Generation
          • Attenuation
          • Amplified Spontaneous Emission Noise
          • Chromatic Dispersion
          • Kerr Nonlinearity
          • Split-Step Fourier Method
          • References
      • Experts
        • 5G Channel Coding and Rate-Matching: Polar vs. LDPC Codes
          • Table of Contents
          • GPU Configuration and Imports
          • BER Performance of 5G Coding Schemes
          • A Deeper Look into the Polar Code Module
          • Rate-Matching and Rate-Recovery
          • Throughput and Decoding Complexity
          • References
        • 5G NR PUSCH Tutorial
          • Table of Contents
          • GPU Configuration and Imports
          • A Hello World Example
          • Carrier Configuration
          • Understanding the DMRS Configuration
          • Transport Blocks and MCS
          • Looking into the PUSCHTransmitter
          • Components of the PUSCHReceiver
          • End-to-end PUSCH Simulations
        • Bit-Interleaved Coded Modulation (BICM)
          • Table of Contents
          • System Block Diagram
          • GPU Configuration and Imports
          • A Simple BICM System
          • All-zero Codeword Simulations
          • EXIT Charts
          • Mismatched Demapping and the Advantages of Min-sum Decoding
          • References
        • MIMO OFDM Transmissions over the CDL Channel Model
          • Table of Contents
          • System Setup
          • Simulations
        • Neural Receiver for OFDM SIMO Systems
          • GPU Configuration and Imports
          • Simulation Parameters
          • Neural Receiver
          • End-to-end System
          • End-to-end System as a Sionna Block
          • Evaluation of the Baselines
          • Training the Neural Receiver
          • Evaluation of the Neural Receiver
          • Pre-computed Results
          • References
        • Realistic Multiuser MIMO OFDM Simulations
          • Table of Contents
          • GPU Configuration and Imports
          • System Setup
          • Uplink Transmissions in the Frequency Domain
        • OFDM MIMO Channel Estimation and Detection
          • Table of Contents
          • GPU Configuration and Imports
          • Simulation parameters
          • Estimation of the channel time, frequency, and spatial covariance matrices
          • Loading the channel covariance matrices
          • Comparison of OFDM estimators
          • Comparison of MIMO detectors
        • Introduction to Iterative Detection and Decoding
          • Iterative Detection and Decoding
          • Table of contents
          • GPU Configuration and Imports
          • Simulation Parameters
          • Setting-up an End-to-end Block
          • Non-IDD versus IDD Benchmarks
          • Discussion-Optimizing IDD with Machine Learning
          • Comments
          • List of References
        • End-to-end Learning with Autoencoders
          • GPU Configuration and Imports
          • Simulation Parameters
          • Neural Demapper
          • Trainable End-to-end System: Conventional Training
          • Trainable End-to-end System: RL-based Training
          • Evaluation
          • Visualizing the Learned Constellations
          • References
        • Weighted Belief Propagation Decoding
          • Table of Contents
          • GPU Configuration and Imports
          • Weighted BP for BCH Codes
          • Further Experiments
          • References
        • Channel Models from Datasets
          • GPU Configuration and Imports
          • Simulation Parameters
          • Creating a Simple Dataset
          • Generators
          • Use the Channel Model for OFDM Transmissions
        • Using the DeepMIMO Dataset with Sionna
          • Table of Contents
          • GPU Configuration and Imports
          • Configuration of DeepMIMO
          • Using DeepMIMO with Sionna
          • Link-level Simulations using Sionna and DeepMIMO
          • DeepMIMO License and Citation
        • Link-level simulations with Sionna RT
          • Background Information
          • Imports
          • Setting up the Ray Tracer
          • Creating a CIR Dataset
          • PUSCH Link-Level Simulations
    • API Documentation
      • Configuration
        • Config
          • Config.np_cdtype
          • Config.np_rdtype
          • Config.np_rng
          • Config.precision
          • Config.py_rng
          • Config.seed
          • Config.tf_cdtype
          • Config.tf_rdtype
          • Config.tf_rng
      • Forward Error Correction (FEC)
        • Linear Codes
          • LinearEncoder
          • OSDecoder
        • Low-Density Parity-Check (LDPC)
          • LDPC5GEncoder
          • LDPCBPDecoder
          • LDPC5GDecoder
          • Node Update Functions
          • Decoder Callbacks
        • Polar Codes
          • Polar5GEncoder
          • PolarEncoder
          • Polar5GDecoder
          • PolarSCDecoder
          • PolarSCLDecoder
          • PolarBPDecoder
          • Utility Functions
        • Convolutional Codes
          • ConvEncoder
          • ViterbiDecoder
          • BCJRDecoder
          • Utility Functions
        • Turbo Codes
          • TurboEncoder
          • TurboDecoder
          • Utility Functions
        • Cyclic Redundancy Check (CRC)
          • CRCEncoder
          • CRCDecoder
        • Interleaving
          • RowColumnInterleaver
          • RandomInterleaver
          • Turbo3GPPInterleaver
          • Deinterleaver
        • Scrambling
          • Scrambler
          • TB5GScrambler
          • Descrambler
        • Utility Functions
          • (Binary) Linear Codes
          • EXIT Analysis
          • Miscellaneous
      • Mapping
        • Constellation
          • Constellation.center
          • Constellation.constellation_type
          • Constellation.normalize
          • Constellation.num_bits_per_symbol
          • Constellation.num_points
          • Constellation.points
          • Constellation.show()
        • Mapper
          • Mapper.constellation
        • Demapper
          • Demapper.constellation
        • SymbolDemapper
        • Utility Functions
          • BinarySource
          • LLRs2SymbolLogits
          • PAMSource
          • PAM2QAM
          • QAMSource
          • QAM2PAM
          • SymbolInds2Bits
          • SymbolLogits2LLRs
          • SymbolLogits2Moments
          • SymbolSource
      • Wireless Channel Models
        • AWGN
        • Flat-fading channel
          • FlatFadingChannel
          • GenerateFlatFadingChannel
          • ApplyFlatFadingChannel
          • SpatialCorrelation
          • KroneckerModel
          • PerColumnModel
        • Channel model interface
          • ChannelModel
        • Time domain channel
          • TimeChannel
          • GenerateTimeChannel
          • ApplyTimeChannel
          • cir_to_time_channel()
          • time_to_ofdm_channel()
        • Channel with OFDM waveform
          • OFDMChannel
          • GenerateOFDMChannel
          • ApplyOFDMChannel
          • cir_to_ofdm_channel()
        • Rayleigh block fading
          • RayleighBlockFading
        • 3GPP 38.901 channel models
          • PanelArray
          • Antenna
          • AntennaArray
          • TDL
          • CDL
          • UMi
          • UMa
          • RMa
        • External datasets
          • CIRDataset
        • Utility functions
          • subcarrier_frequencies()
          • time_lag_discrete_time_channel()
          • deg_2_rad()
          • rad_2_deg()
          • wrap_angle_0_360()
          • drop_uts_in_sector()
          • relocate_uts()
          • set_3gpp_scenario_parameters()
          • gen_single_sector_topology()
          • gen_single_sector_topology_interferers()
          • exp_corr_mat()
          • one_ring_corr_mat()
      • Optical Channel Models
        • SSFM
        • EDFA
        • Utility functions
          • time_frequency_vector()
      • Discrete Channel Models
        • BinaryErasureChannel
        • BinaryMemorylessChannel
          • BinaryMemorylessChannel.llr_max
          • BinaryMemorylessChannel.temperature
        • BinarySymmetricChannel
        • BinaryZChannel
      • Orthogonal Frequency-Division Multiplexing (OFDM)
        • Resource Grid
          • ResourceGrid
          • ResourceGridMapper
          • ResourceGridDemapper
          • RemoveNulledSubcarriers
        • Modulation & Demodulation
          • OFDMModulator
          • OFDMDemodulator
        • Pilot Pattern
          • PilotPattern
          • EmptyPilotPattern
          • KroneckerPilotPattern
        • Channel Estimation
          • BaseChannelEstimator
          • BaseChannelInterpolator
          • LSChannelEstimator
          • LinearInterpolator
          • LMMSEInterpolator
          • NearestNeighborInterpolator
          • tdl_time_cov_mat()
          • tdl_freq_cov_mat()
        • Precoding
          • RZFPrecoder
          • PrecodedChannel
          • CBFPrecodedChannel
          • EyePrecodedChannel
          • RZFPrecodedChannel
        • Equalization
          • OFDMEqualizer
          • LMMSEEqualizer
          • MFEqualizer
          • ZFEqualizer
          • PostEqualizationSINR
          • LMMSEPostEqualizationSINR
        • Detection
          • OFDMDetector
          • OFDMDetectorWithPrior
          • EPDetector
          • KBestDetector
          • LinearDetector
          • MaximumLikelihoodDetector
          • MaximumLikelihoodDetectorWithPrior
          • MMSEPICDetector
      • Multiple-Input Multiple-Output (MIMO)
        • Stream Management
          • StreamManagement
        • Precoding
          • cbf_precoding_matrix()
          • rzf_precoding_matrix()
          • rzf_precoder()
          • grid_of_beams_dft_ula()
          • grid_of_beams_dft()
          • flatten_precoding_mat()
          • normalize_precoding_power()
        • Equalization
          • lmmse_matrix()
          • lmmse_equalizer()
          • mf_equalizer()
          • zf_equalizer()
        • Detection
          • EPDetector
          • KBestDetector
          • LinearDetector
          • MaximumLikelihoodDetector
          • MMSEPICDetector
        • Utility Functions
          • List2LLR
          • List2LLRSimple
          • complex2real_vector()
          • real2complex_vector()
          • complex2real_matrix()
          • real2complex_matrix()
          • complex2real_covariance()
          • real2complex_covariance()
          • complex2real_channel()
          • real2complex_channel()
          • whiten_channel()
      • 5G NR
        • Carrier
          • CarrierConfig
        • Layer Mapping
          • LayerMapper
          • LayerDemapper
        • PUSCH
          • PUSCHConfig
          • PUSCHDMRSConfig
          • PUSCHLSChannelEstimator
          • PUSCHPilotPattern
          • PUSCHPrecoder
          • PUSCHReceiver
          • PUSCHTransmitter
        • Transport Block
          • TBConfig
          • TBEncoder
          • TBDecoder
        • Utils
          • calculate_tb_size()
          • generate_prng_seq()
          • decode_mcs_index()
          • calculate_num_coded_bits()
          • TransportBlockNR
          • CodedAWGNChannelNR
          • MCSDecoderNR
      • Signal
        • Filters
          • SincFilter
          • RaisedCosineFilter
          • RootRaisedCosineFilter
          • CustomFilter
          • Filter
        • Window functions
          • HannWindow
          • HammingWindow
          • BlackmanWindow
          • CustomWindow
          • Window
        • Utility Functions
          • convolve()
          • fft()
          • ifft()
          • Upsampling
          • Downsampling
          • empirical_psd()
          • empirical_aclr()
      • Utility Functions
        • Linear Algebra
          • inv_cholesky()
          • matrix_pinv()
        • Metrics
          • compute_ber()
          • compute_bler()
          • compute_ser()
          • count_block_errors()
          • count_errors()
        • Miscellaneous
          • dbm_to_watt()
          • db_to_lin
          • DeepUpdateDict
          • dict_keys_to_int()
          • ebnodb2no()
          • complex_normal()
          • hard_decisions()
          • Interpolate
          • lin_to_db
          • log2()
          • log10()
          • MCSDecoder
          • scalar_to_shaped_tensor()
          • sim_ber()
          • SingleLinkChannel
          • SplineGriddataInterpolation
          • to_list()
          • TransportBlock
          • watt_to_dbm()
        • Numerics
          • bisection_method()
        • Plotting
          • plot_ber()
          • PlotBER
        • Tensors
          • expand_to_rank()
          • flatten_dims()
          • flatten_last_dims()
          • insert_dims()
          • split_dim()
          • diag_part_axis()
          • flatten_multi_index()
          • gather_from_batched_indices()
          • tensor_values_are_in_set()
          • enumerate_indices()
      • For Developers
        • Object
          • Object.cdtype
          • Object.precision
          • Object.rdtype
        • Block
          • Block.build()
          • Block.built
          • Block.call()
    • Developer Guides
      • Matrix inversion
        • Solving linear systems
        • Correlated random vectors
      • Random number generation
      • Sionna Block and Object
        • Understanding Sionna Blocks
  • System Level (SYS)
    • Tutorials
      • Beginners
        • Physical Layer Abstraction
          • Imports
          • Instantiate a PHYAbstraction object
          • Retrieve BLER values from interpolated tables
          • Generate a new BLER table
          • Bypass physical layer computations
          • Effective SINR
          • Conclusions
          • References
        • Link Adaptation
          • Imports
          • Simulation parameters
          • The principles of link adaptation
          • Inner-Loop Link Adaptation (ILLA)
          • Outer-Loop Link Adaption (OLLA)
          • Conclusions
          • References
        • Proportional Fairness Scheduler
          • Imports
          • The main principle
          • Basic scenario
          • Schedule users
          • Evaluate performance
          • Conclusions
          • References
        • Hexagonal Grid Topology
          • Imports
          • Generate a multicell topology
          • Drop users
          • Set up a 3GPP multicell scenario
          • Per-stream SINR computation
          • Conclusions
        • Power Control
          • Imports
          • Multicell scenario
          • Uplink power control
          • Downlink power control
          • Conclusions
          • References
      • Experts
        • Sionna SYS meets Sionna RT
          • Imports
          • Simulation parameters
          • Scene creation
          • Channel generation via Sionna RT
          • System-level simulation
          • Conclusions
        • System-Level Simulations
          • Imports
          • Utils
          • Simulation
          • Performance metric analysis
          • Conclusions
    • API Documentation
      • PHY Abstraction
        • EffectiveSINR
          • EffectiveSINR.calibrate()
        • EESM
          • EESM.beta_table
          • EESM.beta_table_filenames
          • EESM.beta_tensor
          • EESM.validate_beta_table()
        • PHYAbstraction
          • PHYAbstraction.bler_interp_delta
          • PHYAbstraction.bler_table
          • PHYAbstraction.bler_table_filenames
          • PHYAbstraction.bler_table_interp
          • PHYAbstraction.cbs_interp_min_max_delta
          • PHYAbstraction.get_bler()
          • PHYAbstraction.get_idx_from_grid()
          • PHYAbstraction.load_table()
          • PHYAbstraction.new_bler_table()
          • PHYAbstraction.plot()
          • PHYAbstraction.snr_db_interp_min_max_delta
          • PHYAbstraction.snr_table_interp
          • PHYAbstraction.validate_bler_table()
      • Link Adaptation
        • InnerLoopLinkAdaptation
          • InnerLoopLinkAdaptation.bler_target
        • OuterLoopLinkAdaptation
          • OuterLoopLinkAdaptation.bler_target
          • OuterLoopLinkAdaptation.delta_down
          • OuterLoopLinkAdaptation.delta_up
          • OuterLoopLinkAdaptation.offset
          • OuterLoopLinkAdaptation.offset_max
          • OuterLoopLinkAdaptation.offset_min
          • OuterLoopLinkAdaptation.reset()
          • OuterLoopLinkAdaptation.sinr_eff_db_last
        • Note
      • Power Control
        • Uplink
          • open_loop_uplink_power_control()
        • Downlink
          • downlink_fair_power_control()
      • Scheduling
        • PFSchedulerSUMIMO
          • PFSchedulerSUMIMO.beta
          • PFSchedulerSUMIMO.pf_metric
          • PFSchedulerSUMIMO.rate_achieved_past
      • Multicell Topology
        • Hexagon
          • Hexagon.coord_axial
          • Hexagon.coord_dict()
          • Hexagon.coord_euclid
          • Hexagon.coord_offset
          • Hexagon.corners()
          • Hexagon.neighbor()
          • Hexagon.radius
        • HexGrid
          • HexGrid.cell_height
          • HexGrid.cell_loc
          • HexGrid.cell_radius
          • HexGrid.center_loc
          • HexGrid.grid
          • HexGrid.isd
          • HexGrid.mirror_cell_loc
          • HexGrid.num_cells
          • HexGrid.num_rings
          • HexGrid.show()
        • gen_hexgrid_topology()
        • get_num_hex_in_grid()
        • convert_hex_coord()
      • Utils
        • get_pathloss()
        • is_scheduled_in_slot()
        • spread_across_subcarriers()
  • Research Kit (RK)
    • Quickstart
      • Hardware Requirements
      • Step 1: Jetson Setup
      • Step 2: USRP Setup
      • Step 3: UE Setup
      • Step 4: Deploy 5G Stack
      • Have Your First Call
    • Setup
      • Platform Preparation
        • Bill of Materials
          • Computing Platform
          • RF Components
          • User Equipment
          • Optional Components
        • Jetson Setup
          • OS Installation
          • Post-Installation Setup
          • Version Information
        • Custom Linux Kernel
          • Prerequisites
          • Source Code
          • Kernel Configuration
          • Building the Kernel
          • Installing Kernel Image and Modules
          • Configure Boot Sequence
        • Performance Tweaks
          • Power Management
          • Default System Mode
          • Real-Time Scheduling
          • Verifying Settings
        • USRP Driver Installation
          • Key Resources
          • Prerequisites
          • Building UHD
          • Post-build Configuration
          • Testing Installation
        • SIM Card Programming
          • Prerequisites
          • UICC Software Setup
          • Programming SIM Card
          • Additional Resources
        • Quectel Modem Setup
          • Basic Configuration
          • AT Command Reference
          • Additional Resources
      • Software Configuration
        • OpenAirInterface Setup
          • Required Components
          • TLDR
          • Getting the Source Code
          • Patching
          • Create configuration files
          • Building OAI RAN Images
          • Building OAI 5G Core Images
          • Building Components Manually
        • 5G System Configuration
          • Environment Variables
          • Additional Resources
        • Using RF Simulator Mode
          • Basic Configuration
          • Dynamic Re-configuration
        • Installing Sionna
      • Your First Call
        • Connect & Test Performance
      • Documentation of Scripts
        • Setup Scripts
          • quickstart-oai.sh
          • quickstart-cn5g.sh
          • configure-system.sh
          • install-usrp.sh
        • Linux Kernel Customization
          • build-custom-kernel.sh
          • install-custom-kernel.sh
        • Configuration Files
          • start-system.sh
          • stop-system.sh
          • generate-configs.sh
        • Building Docker Images
          • build-cn5g-images.sh
          • build-oai-images.sh
        • Development / Patch tracking
          • get-config-changes.sh
          • get-oai-changed-files.sh
          • get-oai-cn5g-changed-files.sh
          • get-oai-commit-versions.sh
          • get-oai-cn5g-commit-versions.sh
    • Tutorials
      • Running the Tutorials
        • Command Cheat-sheet
        • GPU-Accelerated LDPC
        • Demapper Plugin
        • Data Capture Plugin
        • TensorRT Neural Demapper
      • GPU-Accelerated LDPC Decoding
        • Part 1: Background & Python Reference Implementation
          • Background: Channel Coding in 5G
          • Overview Decoder Implementation
          • Memory Layout
          • CN Update Function
          • VN Update Function
          • Hard-decision
          • Main Decoding Function
          • Run and Test the Decoder
        • Part 2: CUDA Implementation
          • Overview
          • CUDA Integration in OAI
          • Running the Decoder
          • Implementation Aspects
          • Outlook - Weighted Belief Propagation
        • References
      • Plugins & Data Acquisition
        • Part 1: Create a Plugin
          • Architecture Overview
          • Select Functions
          • Define Module Interface
          • Loading the Module
          • Use Module Functions
          • Module Implementation
          • Compiling
          • Incremental Builds
          • Container Changes
        • Part 2: Capture Data
          • Adding New Plugin Variant
          • Using New Plugin Variant
          • Access Captured Files
          • Capture Format
          • Add Timestamps
          • Account for Multi-Threading
          • Final Source Code
        • References
      • Integration of a Neural Demapper
        • Part 1: Neural Demapper Training and TensorRT Export
          • Python Imports
          • Background: APP-Demapping
          • Understanding the OAI Data Structure
          • Neural Demapper
          • Blind Demapping & Training with Synthetic Data
          • Improved Demapping & Training with Captured Data
          • Export TensorRT Engine
        • Part 2: GPU-Accelerated Inference
          • Demapper Implementation Overview
          • Setting up the TensorRT Inference Engine
          • Running Batched Inference
          • Converting Data Types between Host and Device
          • Demapper Integration in OAI
          • Running the Demapper
          • Implementation Aspects
          • Unit tests
          • Outlook
        • References
      • Software-defined End-to-End 5G Network
        • Run the gNB
        • Run the UE
        • Test performance
      • Debugging & Troubleshooting
        • Attaching a debugger (gdb and VS code)
        • Inspecting and debugging inside a container interactively
        • Running memcheck within an interactive Docker compose session
        • Profiling with NVIDIA Nsight Systems
        • Fixing missing linker error messages in docker build ran-build
    • Get the Code
  • “Made with Sionna”
  • Discussions
  • Report an Issue
  • Contribute
  • Citation

Older Versions

  • v0.19.2
Sionna
  • Physical Layer (PHY)
  • Tutorials
  • Part 3: Advanced Link-level Simulations

Colab logo Run in Google Colab View on GitHub Download notebook

Part 3: Advanced Link-level Simulations

This tutorial will guide you through Sionna, from its basic principles to the implementation of a point-to-point link with a 5G NR compliant code and a 3GPP channel model. You will also learn how to write custom trainable blocks by implementing a state of the art neural receiver, and how to train and evaluate end-to-end communication systems.

The tutorial is structured in four notebooks:

  • Part I: Getting started with Sionna

  • Part II: Differentiable Communication Systems

  • Part III: Advanced Link-level Simulations

  • Part IV: Toward Learned Receivers

The official documentation provides key material on how to use Sionna and how its components are implemented.

  • Imports

  • OFDM Resource Grid and Stream Management

  • Antenna Arrays

  • Channel Model

  • Uplink Transmission in the Frequency Domain

Imports

[1]:
import os # Configure which GPU
if os.getenv("CUDA_VISIBLE_DEVICES") is None:
    gpu_num = 0 # Use "" to use the CPU
    os.environ["CUDA_VISIBLE_DEVICES"] = f"{gpu_num}"

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

# Import Sionna
try:
    import sionna as sn
    import sionna.phy
except ImportError as e:
    import sys
    if 'google.colab' in sys.modules:
       # Install Sionna in Google Colab
       print("Installing Sionna and restarting the runtime. Please run the cell again.")
       os.system("pip install sionna")
       os.kill(os.getpid(), 5)
    else:
       raise e

# Configure the notebook to use only a single GPU and allocate only as much memory as needed
# For more details, see https://www.tensorflow.org/guide/gpu
import tensorflow as tf
gpus = tf.config.list_physical_devices('GPU')
if gpus:
    try:
        tf.config.experimental.set_memory_growth(gpus[0], True)
    except RuntimeError as e:
        print(e)

# Avoid warnings from TensorFlow
tf.get_logger().setLevel('ERROR')

import numpy as np

# For plotting
%matplotlib inline
import matplotlib.pyplot as plt

# For the implementation of the Keras models
from tensorflow.keras import Model

# Set seed for reproducable results
sn.phy.config.seed = 42

OFDM Resource Grid and Stream Management

We will setup a realistic SIMO point-to-point link between a mobile user terminal (UT) and a base station (BS). The system we will setup is shown in the figure below.

SIMO

Stream Management

For any type of MIMO simulations, it is required to setup a StreamManagement object. It determines which transmitters and receivers communicate data streams with each other. In our scenario, we will configure a single UT equipped with a single antenna and a single BS equipped with multiple antennas. Whether the UT or BS is considered as a transmitter depends on the link direction, which can be either uplink or downlink. The StreamManagement has many properties that are used by other components, such as precoding and equalization.

We will configure the system here such that the number of streams per transmitter is equal to the number of UT antennas.

[2]:
# Define the number of UT and BS antennas
NUM_UT = 1
NUM_BS = 1
NUM_UT_ANT = 1
NUM_BS_ANT = 4

# The number of transmitted streams is equal to the number of UT antennas
# in both uplink and downlink
NUM_STREAMS_PER_TX = NUM_UT_ANT

# Create an RX-TX association matrix.
# RX_TX_ASSOCIATION[i,j]=1 means that receiver i gets at least one stream
# from transmitter j. Depending on the transmission direction (uplink or downlink),
# the role of UT and BS can change.
# For example, considering a system with 2 RX and 4 TX, the RX-TX
# association matrix could be
# [ [1 , 1, 0, 0],
#   [0 , 0, 1, 1] ]
# which indicates that the RX 0 receives from TX 0 and 1, and RX 1 receives from
# TX 2 and 3.
#
# In this notebook, as we have only a single transmitter and receiver,
# the RX-TX association matrix is simply:
RX_TX_ASSOCIATION = np.array([[1]])

# Instantiate a StreamManagement object
# This determines which data streams are determined for which receiver.
# In this simple setup, this is fairly easy. However, it can get more involved
# for simulations with many transmitters and receivers.
STREAM_MANAGEMENT = sn.phy.mimo.StreamManagement(RX_TX_ASSOCIATION, NUM_STREAMS_PER_TX)

OFDM Resource Grid

Next, we configure an OFDM ResourceGrid spanning multiple OFDM symbols. The resource grid contains data symbols and pilots and is equivalent to a slot in 4G/5G terminology. Although it is not relevant for our simulation, we null the DC subcarrier and a few guard carriers to the left and right of the spectrum. Also a cyclic prefix is added.

During the creation of the ResourceGrid, a PilotPattern is automatically generated. We could have alternatively created a PilotPattern first and then provided it as initialization parameter. When multiple streams are considered, the corresponding pilot patterns must be orthogonal. By default, orthogonal pilots are setup when considering such systems.

[3]:
RESOURCE_GRID = sn.phy.ofdm.ResourceGrid(num_ofdm_symbols=14,
                                         fft_size=76,
                                         subcarrier_spacing=30e3,
                                         num_tx=NUM_UT,
                                         num_streams_per_tx=NUM_STREAMS_PER_TX,
                                         cyclic_prefix_length=6,
                                         pilot_pattern="kronecker",
                                         pilot_ofdm_symbol_indices=[2,11])
RESOURCE_GRID.show();
../../_images/phy_tutorials_Sionna_tutorial_part3_13_0.png
[4]:
RESOURCE_GRID.pilot_pattern.show();
../../_images/phy_tutorials_Sionna_tutorial_part3_14_0.png

Task: You can try different pilot patterns, FFT size, number of OFDM symbols, and visualize how it affects the resource grid.

See the notebook MIMO OFDM Transmissions over CDL for more advanced examples.

Antenna Arrays

We need to configure the antenna arrays used by the UT and BS. This can be ignored for simple channel models, such as AWGN, RayleighBlockFading, or TDL which do not account for antenna array geometries and antenna radiation patterns. However, other models, such as CDL, UMi, UMa, and RMa from the 3GPP 38.901 specification, require it.

We will assume here that UT is equipped with one vertically single-polarized antenna and the BS antenna array is composed of dual cross-polarized antenna elements with an antenna pattern defined in the 3GPP 38.901 specification. By default, the antenna elements are spaced half of a wavelength apart in both vertical and horizontal directions. You can define your own antenna geometries an radiation patterns if needed.

An AntennaArray is always defined in the y-z plane. Its final orientation will be determined by the orientation of the UT or BS. This parameter can be configured in the ChannelModel that we will create later.

[5]:
CARRIER_FREQUENCY = 2.6e9 # Carrier frequency in Hz.
                          # This is needed here to define the antenna element spacing.

UT_ARRAY = sn.phy.channel.tr38901.Antenna(polarization="single",
                                          polarization_type="V",
                                          antenna_pattern="38.901",
                                          carrier_frequency=CARRIER_FREQUENCY)
UT_ARRAY.show();

BS_ARRAY = sn.phy.channel.tr38901.AntennaArray(num_rows=1,
                                               num_cols=int(NUM_BS_ANT/2),
                                               polarization="dual",
                                               polarization_type="cross",
                                               antenna_pattern="38.901", # Try 'omni'
                                               carrier_frequency=CARRIER_FREQUENCY)
BS_ARRAY.show();
../../_images/phy_tutorials_Sionna_tutorial_part3_18_0.png
../../_images/phy_tutorials_Sionna_tutorial_part3_18_1.png
[6]:
BS_ARRAY.show_element_radiation_pattern();
../../_images/phy_tutorials_Sionna_tutorial_part3_19_0.png
../../_images/phy_tutorials_Sionna_tutorial_part3_19_1.png
../../_images/phy_tutorials_Sionna_tutorial_part3_19_2.png

Task: You can try different antenna pattern (“omni”), polarization, and array geometries.

Channel Model

Sionna implements the CDL, TDL, UMi, UMa, and RMa models from 3GPP TR 38.901, as well as Rayleigh block fading.

Note that:

  • TDL only supports SISO

  • CDL only supports single-user, possibly with multiple antenna

  • UMi, UMa, and RMa support single- and multi-user

Remark: The TDL and CDL models correspond to fixed power delay profiles and fixed angles.

SIMO channel

We consider the 3GPP CDL model family in this notebook.

[7]:
DELAY_SPREAD = 100e-9 # Nominal delay spread in [s]. Please see the CDL documentation
                      # about how to choose this value.

DIRECTION = "uplink"  # The `direction` determines if the UT or BS is transmitting.
                      # In the `uplink`, the UT is transmitting.

CDL_MODEL = "C"       # Suitable values are ["A", "B", "C", "D", "E"]

SPEED = 10.0          # UT speed [m/s]. BSs are always assumed to be fixed.
                     # The direction of travel will chosen randomly within the x-y plane.

# Configure a channel impulse reponse (CIR) generator for the CDL model.
CDL = sn.phy.channel.tr38901.CDL(CDL_MODEL,
                                 DELAY_SPREAD,
                                CARRIER_FREQUENCY,
                                UT_ARRAY,
                                BS_ARRAY,
                                DIRECTION,
                                min_speed=SPEED)

The instance CDL of the CDL model can be used to generate batches of random realizations of continuous-time channel impulse responses, consisting of complex gains a and delays tau for each path. To account for time-varying channels, a channel impulse responses is sampled at the sampling_frequency for num_time_samples samples. For more details on this, please have a look at the API documentation of the channel models.

In order to model the channel in the frequency domain, we need num_ofdm_symbols samples that are taken once per ofdm_symbol_duration, which corresponds to the length of an OFDM symbol plus the cyclic prefix.

[8]:
BATCH_SIZE = 128 # How many examples are processed by Sionna in parallel

a, tau = CDL(batch_size=BATCH_SIZE,
             num_time_steps=RESOURCE_GRID.num_ofdm_symbols,
             sampling_frequency=1/RESOURCE_GRID.ofdm_symbol_duration)
The path gains a have shape
[batch size, num_rx, num_rx_ant, num_tx, num_tx_ant, num_paths, num_time_steps]
and the delays tau have shape
[batch_size, num_rx, num_tx, num_paths].
[9]:
print("Shape of the path gains: ", a.shape)
print("Shape of the delays:", tau.shape)
Shape of the path gains:  (128, 1, 4, 1, 1, 24, 14)
Shape of the delays: (128, 1, 1, 24)

The delays are assumed to be static within the time-window of interest. Only the complex path gains change over time. The following two figures depict the channel impulse response at a particular time instant and the time-evolution of the gain of one path, respectively.

[10]:
plt.figure()
plt.title("Channel impulse response realization")
plt.stem(tau[0,0,0,:]/1e-9, np.abs(a)[0,0,0,0,0,:,0])
plt.xlabel(r"$\tau$ [ns]")
plt.ylabel(r"$|a|$")

plt.figure()
plt.title("Time evolution of path gain")
plt.plot(np.arange(RESOURCE_GRID.num_ofdm_symbols)*RESOURCE_GRID.ofdm_symbol_duration/1e-6, np.real(a)[0,0,0,0,0,0,:])
plt.plot(np.arange(RESOURCE_GRID.num_ofdm_symbols)*RESOURCE_GRID.ofdm_symbol_duration/1e-6, np.imag(a)[0,0,0,0,0,0,:])
plt.legend(["Real part", "Imaginary part"])

plt.xlabel(r"$t$ [us]")
plt.ylabel(r"$a$");
../../_images/phy_tutorials_Sionna_tutorial_part3_31_0.png
../../_images/phy_tutorials_Sionna_tutorial_part3_31_1.png

See the notebook Realistic Multiuser MIMO Simulations for more advanced examples.

Uplink Transmission in the Frequency Domain

We are now ready to simulate a transmission.

In the following, the channel is simulated in the frequency domain. Therefore, the channel is assumed to be constant over the duration of an OFDM symbol, which leads to not simulating the intercarrier interference (ICI) that could occur due to channel aging over the duration of OFDM symbols.

The OFDMChannel layer is used to simulate the channel in the frequency domain and takes care of sampling channel impulse responses, computing the frequency responses, and applying the channel transfer function to the channel inputs (including AWGN).

Note that it is also possible to simulate the channel in time domain using the TimeChannel layer, which enables simulation of ICI. For more information, please have a look at the API documentation.

[11]:
NUM_BITS_PER_SYMBOL = 2 # QPSK
CODERATE = 0.5

# Number of coded bits in a resource grid
n = int(RESOURCE_GRID.num_data_symbols*NUM_BITS_PER_SYMBOL)
# Number of information bits in a resource groud
k = int(n*CODERATE)

# The binary source will create batches of information bits
binary_source = sn.phy.mapping.BinarySource()

# The encoder maps information bits to coded bits
encoder = sn.phy.fec.ldpc.LDPC5GEncoder(k, n)

# The mapper maps blocks of information bits to constellation symbols
mapper = sn.phy.mapping.Mapper("qam", NUM_BITS_PER_SYMBOL)

# The resource grid mapper maps symbols onto an OFDM resource grid
rg_mapper = sn.phy.ofdm.ResourceGridMapper(RESOURCE_GRID)

# Frequency domain channel
channel = sn.phy.channel.OFDMChannel(CDL, RESOURCE_GRID, add_awgn=True, normalize_channel=True, return_channel=True)

# The LS channel estimator will provide channel estimates and error variances
ls_est = sn.phy.ofdm.LSChannelEstimator(RESOURCE_GRID, interpolation_type="nn")

# The LMMSE equalizer will provide soft symbols together with noise variance estimates
lmmse_equ = sn.phy.ofdm.LMMSEEqualizer(RESOURCE_GRID, STREAM_MANAGEMENT)

# The demapper produces LLR for all coded bits
demapper = sn.phy.mapping.Demapper("app", "qam", NUM_BITS_PER_SYMBOL)

# The decoder provides hard-decisions on the information bits
decoder = sn.phy.fec.ldpc.LDPC5GDecoder(encoder, hard_out=True)

Let’s now simulate the transmission, and look at the shape of the layers outputs at each stage.

The utility function ebnodb2no takes as additional input the resource grid to account for the pilots when computing the noise power spectral density ratio N0 from the energy per bit to noise power spectral density ratio Eb/N0 (in dB).

[12]:
no = sn.phy.utils.ebnodb2no(ebno_db=10.0,
                            num_bits_per_symbol=NUM_BITS_PER_SYMBOL,
                            coderate=CODERATE,
                            resource_grid=RESOURCE_GRID)

# Transmitter
bits = binary_source([BATCH_SIZE, NUM_UT, RESOURCE_GRID.num_streams_per_tx, k])
print("Shape of bits: ", bits.shape)
codewords = encoder(bits)
print("Shape of codewords: ", codewords.shape)
x = mapper(codewords)
print("Shape of x: ", x.shape)
x_rg = rg_mapper(x)
print("Shape of x_rg: ", x_rg.shape)

# Channel
y, h_freq = channel(x_rg, no)
print("Shape of y_rg: ", y.shape)
print("Shape of h_freq: ", h_freq.shape)

# Receiver
h_hat, err_var = ls_est (y, no)
print("Shape of h_hat: ", h_hat.shape)
print("Shape of err_var: ", err_var.shape)
x_hat, no_eff = lmmse_equ(y, h_hat, err_var, no)
print("Shape of x_hat: ", x_hat.shape)
print("Shape of no_eff: ", no_eff.shape)
llr = demapper(x_hat, no_eff)
print("Shape of llr: ", llr.shape)
bits_hat = decoder(llr)
print("Shape of bits_hat: ", bits_hat.shape)
Shape of bits:  (128, 1, 1, 912)
Shape of codewords:  (128, 1, 1, 1824)
Shape of x:  (128, 1, 1, 912)
Shape of x_rg:  (128, 1, 1, 14, 76)
Shape of y_rg:  (128, 1, 4, 14, 76)
Shape of h_freq:  (128, 1, 4, 1, 1, 14, 76)
Shape of h_hat:  (128, 1, 4, 1, 1, 14, 76)
Shape of err_var:  (1, 1, 1, 1, 1, 14, 76)
Shape of x_hat:  (128, 1, 1, 912)
Shape of no_eff:  (128, 1, 1, 912)
Shape of llr:  (128, 1, 1, 1824)
Shape of bits_hat:  (128, 1, 1, 912)

The next cell implements the previous system as an end-to-end model.

Moreover, a boolean given as parameter to the initializer enables using either LS estimation or perfect CSI, as shown in the figure below.

Simo channel LS PCSI
[13]:
class OFDMSystem(Model): # Inherits from Keras Model

    def __init__(self, perfect_csi):
        super().__init__() # Must call the Keras model initializer

        self.perfect_csi = perfect_csi

        n = int(RESOURCE_GRID.num_data_symbols*NUM_BITS_PER_SYMBOL) # Number of coded bits
        k = int(n*CODERATE) # Number of information bits
        self.k = k

        # The binary source will create batches of information bits
        self.binary_source = sn.phy.mapping.BinarySource()

        # The encoder maps information bits to coded bits
        self.encoder = sn.phy.fec.ldpc.LDPC5GEncoder(k, n)

        # The mapper maps blocks of information bits to constellation symbols
        self.mapper = sn.phy.mapping.Mapper("qam", NUM_BITS_PER_SYMBOL)

        # The resource grid mapper maps symbols onto an OFDM resource grid
        self.rg_mapper = sn.phy.ofdm.ResourceGridMapper(RESOURCE_GRID)

        # Frequency domain channel
        self.channel = sn.phy.channel.OFDMChannel(CDL, RESOURCE_GRID, add_awgn=True, normalize_channel=True, return_channel=True)

        # The LS channel estimator will provide channel estimates and error variances
        self.ls_est = sn.phy.ofdm.LSChannelEstimator(RESOURCE_GRID, interpolation_type="nn")

        # The LMMSE equalizer will provide soft symbols together with noise variance estimates
        self.lmmse_equ = sn.phy.ofdm.LMMSEEqualizer(RESOURCE_GRID, STREAM_MANAGEMENT)

        # The demapper produces LLR for all coded bits
        self.demapper = sn.phy.mapping.Demapper("app", "qam", NUM_BITS_PER_SYMBOL)

        # The decoder provides hard-decisions on the information bits
        self.decoder = sn.phy.fec.ldpc.LDPC5GDecoder(self.encoder, hard_out=True)

    @tf.function # Graph execution to speed things up
    def __call__(self, batch_size, ebno_db):
        no = sn.phy.utils.ebnodb2no(ebno_db, num_bits_per_symbol=NUM_BITS_PER_SYMBOL, coderate=CODERATE, resource_grid=RESOURCE_GRID)

        # Transmitter
        bits = self.binary_source([batch_size, NUM_UT, RESOURCE_GRID.num_streams_per_tx, self.k])
        codewords = self.encoder(bits)
        x = self.mapper(codewords)
        x_rg = self.rg_mapper(x)

        # Channel
        y, h_freq = self.channel(x_rg, no)

        # Receiver
        if self.perfect_csi:
            h_hat, err_var = h_freq, 0.
        else:
            h_hat, err_var = self.ls_est (y, no)
        x_hat, no_eff = self.lmmse_equ(y, h_hat, err_var, no)
        llr = self.demapper(x_hat, no_eff)
        bits_hat = self.decoder(llr)

        return bits, bits_hat
[14]:
EBN0_DB_MIN = -8.0 # Minimum value of Eb/N0 [dB] for simulations
EBN0_DB_MAX = 3.0 # Maximum value of Eb/N0 [dB] for simulations

ber_plots = sn.phy.utils.PlotBER("OFDM over 3GPP CDL")

model_ls = OFDMSystem(False)
ber_plots.simulate(model_ls,
                  ebno_dbs=np.linspace(EBN0_DB_MIN, EBN0_DB_MAX, 20),
                  batch_size=BATCH_SIZE,
                  num_target_block_errors=100, # simulate until 100 block errors occured
                  legend="LS Estimation",
                  soft_estimates=True,
                  max_mc_iter=100, # run 100 Monte-Carlo simulations (each with batch_size samples)
                  show_fig=False);

model_pcsi = OFDMSystem(True)
ber_plots.simulate(model_pcsi,
                  ebno_dbs=np.linspace(EBN0_DB_MIN, EBN0_DB_MAX, 20),
                  batch_size=BATCH_SIZE,
                  num_target_block_errors=100, # simulate until 100 block errors occured
                  legend="Perfect CSI",
                  soft_estimates=True,
                  max_mc_iter=100, # run 100 Monte-Carlo simulations (each with batch_size samples)
                  show_fig=False);

ber_plots();
EbNo [dB] |        BER |       BLER |  bit errors |    num bits | block errors |  num blocks | runtime [s] |    status
---------------------------------------------------------------------------------------------------------------------------------------
     -8.0 | 4.3035e-01 | 1.0000e+00 |       50237 |      116736 |          128 |         128 |         8.1 |reached target block errors
   -7.421 | 4.2089e-01 | 1.0000e+00 |       49133 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -6.842 | 4.0998e-01 | 1.0000e+00 |       47860 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -6.263 | 4.0063e-01 | 1.0000e+00 |       46768 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -5.684 | 3.8746e-01 | 1.0000e+00 |       45231 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -5.105 | 3.7554e-01 | 1.0000e+00 |       43839 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -4.526 | 3.5852e-01 | 1.0000e+00 |       41852 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -3.947 | 3.4360e-01 | 1.0000e+00 |       40110 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -3.368 | 3.2968e-01 | 1.0000e+00 |       38485 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -2.789 | 3.1149e-01 | 1.0000e+00 |       36362 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -2.211 | 2.8992e-01 | 1.0000e+00 |       33844 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -1.632 | 2.6465e-01 | 1.0000e+00 |       30894 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -1.053 | 2.3882e-01 | 1.0000e+00 |       27879 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -0.474 | 2.0660e-01 | 1.0000e+00 |       24118 |      116736 |          128 |         128 |         0.1 |reached target block errors
    0.105 | 1.6291e-01 | 9.9219e-01 |       19017 |      116736 |          127 |         128 |         0.1 |reached target block errors
    0.684 | 3.3584e-02 | 4.9219e-01 |        7841 |      233472 |          126 |         256 |         0.2 |reached target block errors
    1.263 | 3.7955e-04 | 1.2139e-02 |        2880 |     7587840 |          101 |        8320 |         5.0 |reached target block errors
    1.842 | 0.0000e+00 | 0.0000e+00 |           0 |    11673600 |            0 |       12800 |         7.8 |reached max iterations

Simulation stopped as no error occurred @ EbNo = 1.8 dB.

EbNo [dB] |        BER |       BLER |  bit errors |    num bits | block errors |  num blocks | runtime [s] |    status
---------------------------------------------------------------------------------------------------------------------------------------
     -8.0 | 2.7901e-01 | 1.0000e+00 |       32570 |      116736 |          128 |         128 |         2.6 |reached target block errors
   -7.421 | 2.6349e-01 | 1.0000e+00 |       30759 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -6.842 | 2.4822e-01 | 1.0000e+00 |       28976 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -6.263 | 2.2700e-01 | 1.0000e+00 |       26499 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -5.684 | 2.0336e-01 | 1.0000e+00 |       23740 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -5.105 | 1.7230e-01 | 1.0000e+00 |       20114 |      116736 |          128 |         128 |         0.1 |reached target block errors
   -4.526 | 1.0627e-01 | 9.6875e-01 |       12405 |      116736 |          124 |         128 |         0.1 |reached target block errors
   -3.947 | 1.4798e-02 | 3.9453e-01 |        3455 |      233472 |          101 |         256 |         0.1 |reached target block errors
   -3.368 | 1.0475e-04 | 8.4918e-03 |        1125 |    10739712 |          100 |       11776 |         7.0 |reached target block errors
   -2.789 | 1.1993e-06 | 1.5625e-04 |          14 |    11673600 |            2 |       12800 |         7.6 |reached max iterations
   -2.211 | 0.0000e+00 | 0.0000e+00 |           0 |    11673600 |            0 |       12800 |         7.6 |reached max iterations

Simulation stopped as no error occurred @ EbNo = -2.2 dB.

../../_images/phy_tutorials_Sionna_tutorial_part3_41_1.png
Previous Next

© Copyright 2021-2025 NVIDIA CORPORATION.

Built with Sphinx using a theme provided by Read the Docs.