NVIDIA - Sionna   

 

 

 

Basic - FEC (Forward Error Correction)

In this note, I will write a script which is an interactive Python application for exploring Forward Error Correction (FEC) codes used in 5G NR systems. The tool leverages NVIDIA's Sionna library to simulate and visualize the performance of Polar 5G and LDPC 5G codes with various modulation schemes over an AWGN channel. It provides a comprehensive Tkinter-based GUI with real-time BER vs. SNR plotting, detailed code parameter analysis, and bit-level visualization.

Followings are brief descriptions on each procedure with the focus on sionna api

  • BinarySource: Generates random information bits u with shape [batch, k].
  • Encoder:
    •   Polar5GEncoder(k, n) or LDPC5GEncoder(k, n) produces codeword c of length n.
    •   For LDPC 5G, the encoder applies puncturing (first 2*Zc bits not transmitted).
  • Mapper: Mapper("qam", num_bits_per_symbol=bps) maps bits to constellation symbols.
  • AWGN Channel: AWGN() adds Gaussian noise using no = ebnodb2no(ebno_db, bps, coderate).
  • Demapper: Demapper("app", "qam", bps) computes soft LLRs for each transmitted bit.
  • Decoder:
    •   Polar5GDecoder(encoder, dec_type="SCL", list_size=8) or LDPC5GDecoder(encoder, num_iter=20) returns decoded bits u_hat.
    •   LDPC decoder internally de-punctures by inserting LLR=0 at punctured positions.
  • BER & Displays: Compare u vs. u_hat to compute BER; update BER plot, status bar, and bit text boxes (info/encoded/decoded).

Toolkits for the script

I didn't write the code myself. What I did was just prompting for AI tool and did basic check up for the output. Followings are the tool kits that I used for this script

  • Scripting IDE : Cursor
    • Version: 2.1.50 (system setup)
    • VSCode Version: 1.105.1
    • Commit: 56f0a83df8e9eb48585fcc4858a9440db4cc7770
    • Date: 2025-12-06T23:39:52.834Z
    • Electron: 37.7.0
    • Chromium: 138.0.7204.251
    • Node.js: 22.20.0
    • V8: 13.8.258.32-electron.0
    • OS: Windows_NT x64 10.0.26100
  • Scripting IDE : Antigravity
    • Antigravity Version: 1.11.17
    • VSCode OSS Version: 1.104.0 (user setup)
    • Commit: c595276fa83d83a7c3233d582e4120f92017171c
    • Date: 2025-12-08T23:18:46.541Z (17 hrs ago)
    • Electron: 37.3.1
    • Chromium: 138.0.7204.235
    • Node.js: 22.18.0
    • V8: 13.8.258.31-electron.0
    • OS: Windows_NT x64 10.0.26100
    • Language Server CL: 841922742
  • AI Model : Auto(as of Dec 9, 2025)/Cursor, Gemini Pro (High)/Antigravity
  • Python Info : Check out this note for the detailed installation proces that I went through
  • ==== Python Version ====

    3.12.3 (main, Nov  6 2025, 13:44:16) [GCC 13.3.0]

     

    ==== Python Executable ====

    /home/jaeku/nvidia/venv-sionna/bin/python3

     

    ==== Platform Info ====

    Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.39

    ('main', 'Nov  6 2025 13:44:16')

     

    ==== Site-Packages Directories ====

    ['/home/jaeku/nvidia/venv-sionna/lib/python3.12/site-packages', '/home/jaeku/nvidia/venv-sionna/local/lib/python3.12/dist-packages', '/home/jaeku/nvidia/venv-sionna/lib/python3/dist-packages', '/home/jaeku/nvidia/venv-sionna/lib/python3.12/dist-packages']

     

    ==== sys.path ====

      /home/jaeku/nvidia

      /usr/lib/python312.zip

      /usr/lib/python3.12

      /usr/lib/python3.12/lib-dynload

      /home/jaeku/nvidia/venv-sionna/lib/python3.12/site-packages

     

    ==== Installed Packages ====

    absl-py == 2.3.1

    asttokens == 3.0.1

    astunparse == 1.6.3

    certifi == 2025.11.12

    charset-normalizer == 3.4.4

    comm == 0.2.3

    contourpy == 1.3.3

    cycler == 0.12.1

    decorator == 5.2.1

    drjit == 1.2.0

    executing == 2.2.1

    flatbuffers == 25.9.23

    fonttools == 4.61.0

    gast == 0.7.0

    google-pasta == 0.2.0

    grpcio == 1.76.0

    h5py == 3.15.1

    idna == 3.11

    importlib_resources == 6.5.2

    ipydatawidgets == 4.3.5

    ipython == 9.8.0

    ipython_pygments_lexers == 1.1.1

    ipywidgets == 8.1.8

    jedi == 0.19.2

    jupyterlab_widgets == 3.0.16

    keras == 3.12.0

    kiwisolver == 1.4.9

    libclang == 18.1.1

    Markdown == 3.10

    markdown-it-py == 4.0.0

    MarkupSafe == 3.0.3

    matplotlib == 3.10.7

    matplotlib-inline == 0.2.1

    mdurl == 0.1.2

    mitsuba == 3.7.1

    ml_dtypes == 0.5.4

    namex == 0.1.0

    numpy == 1.26.4

    opt_einsum == 3.4.0

    optree == 0.18.0

    packaging == 25.0

    parso == 0.8.5

    pexpect == 4.9.0

    pillow == 12.0.0

    pip == 25.3

    prompt_toolkit == 3.0.52

    protobuf == 6.33.2

    ptyprocess == 0.7.0

    pure_eval == 0.2.3

    Pygments == 2.19.2

    pyparsing == 3.2.5

    python-dateutil == 2.9.0.post0

    pythreejs == 2.4.2

    requests == 2.32.5

    rich == 14.2.0

    scipy == 1.16.3

    setuptools == 80.9.0

    sionna == 1.2.1

    sionna-rt == 1.2.1

    six == 1.17.0

    stack-data == 0.6.3

    tensorboard == 2.20.0

    tensorboard-data-server == 0.7.2

    tensorflow == 2.20.0

    termcolor == 3.2.0

    traitlets == 5.14.3

    traittypes == 0.2.3

    typing_extensions == 4.15.0

    urllib3 == 2.6.0

    wcwidth == 0.2.14

    Werkzeug == 3.1.4

    wheel == 0.45.1

    widgetsnbextension == 4.0.15

    wrapt == 2.0.1

Source Code and Output

You can get the source code for this note here.  I would not describe / explain on every single line of the code since AI (e.g, chatGPT, Gemini etc) will explain better than I do.

Disclaimer !!!

    I have checked and fixed some obvious issues of the script while I am prompting the script, but I haven't verified all the details of the implementation. So there likely to be bugs / errors that I missed.  So take this purely as an educational purpose for getting some high level idea on how 3GPP NR Phy specification can be implemented

 

The script output some part of the result in text and some part in graphics.

Followings are the output of the code in text

======================================================================

POLAR 5G CODE PARAMETERS

======================================================================

 

Polar Code Length (n): 256

Info Bits (k): 139

Number of Frozen Bits: 117

Frozen Bit Positions: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]...

 

----------------------------------------------------------------------

GENERAL CODE PARAMETERS

----------------------------------------------------------------------

Code Rate: R = k/n = 128/256 = 0.5000

Info Bits (k): 128

Codeword Length (n): 256

Parity Bits (n-k): 128

Constellation: 16-QAM

 

=====================================================================

LDPC 5G CODE PARAMETERS

======================================================================

 

 

======================================================================

3GPP SPECIFICATION CALCULATION

======================================================================

 

Base Graph (BG) Selection (3GPP TS 38.212 Section 5.3.2.1):

  Transport Size A = 128

  Code Rate R = k/n = 128/256 = 0.5000

 

  Rules (applied sequentially):

  1. A <= 292? Yes (128 <= 292) → BG2 ✓ (applied)

  Calculated BG: BG2

 

Lifting Size (Zc) Selection (3GPP TS 38.212 Section 5.3.2.2):

  For BG2: kb is variable based on code block size B = K = 128

    Rule: B ≤ 192 → kb = 6

    Selected kb = 6

  Kb = min(kb, K) = min(6, 128) = 6

  Find smallest Zc such that Kb * Zc >= K

  6 * Zc >= 128

  Zc >= 21.33

  Selected Zc: 22 (from set index 5)

  Verification: 6 * 22 = 132 >= 128 ✓

 

======================================================================

SIONNA LIBRARY VALUES (for comparison)

======================================================================

Lifting Size (Zc) from Sionna: 22

Set Index (i_LS) from Sionna: 5 (from 3GPP TS 38.212 Table 5.3.2-2)

  Lifting size set: [11, 22, 44, 88, 176, 352]

  ✓ Match: Calculated Zc (22) = Sionna Zc (22)

Punctured Bits (2*Zc): 44

 

Transmitted Bits (n - 2*Zc): 212

Effective Code Rate: R_eff = k/(n-2*Zc) = 128/212 = 0.6038

  (This matches 3GPP CQI/MCS table values)

Base Graph from Sionna: BG2

  ✓ Match: Calculated BG (BG2) = Sionna BG (BG2)

Information Columns (kb): Not available

 

======================================================================

P(i,j) SHIFT VALUES MATRIX

======================================================================

 

⚠️  P(i,j) matrix not available

 

The load_5g_ldpc_graph function is not available in your

Sionna installation. This could be due to:

  1. Your Sionna version doesn't include this function

  2. The function is in a different module location

  3. The function name or API has changed

 

To fix this:

  - Try updating Sionna: pip install --upgrade sionna

  - Check Sionna documentation for the correct import path

  - The function may be available in newer versions

 

----------------------------------------------------------------------

GENERAL CODE PARAMETERS

----------------------------------------------------------------------

Nominal Code Rate: R = k/n = 128/256 = 0.5000

Effective Code Rate: R_eff = k/(n-2*Zc) = 128/212 = 0.6038

  (Note: Effective rate accounts for 44 punctured bits)

Info Bits (k): 128

Codeword Length (n): 256

Parity Bits (n-k): 128

Constellation: 16-QAM

Followings are the snapshots of graphical output (NOTE : If you want to get images for better resolution, I would suggest you to install the sionna on your PC and run the script that I shared).

Polar code Performance

This figure shows the end-to-end performance result of the tutorial script using a 5G NR Polar code.

The simulation follows the full digital chain illustrated earlier—binary data generation, Polar encoding, QAM mapping, AWGN channel, demapping, Polar decoding, and BER measurement—and visualizes how reliably the original bits can be recovered as Eb/N0 increases.

Key points illustrated in the result are as follows

  • Coding scheme: 5G NR Polar code with information bits K = 128 and codeword length N = 256, so the code rate is R = K/N = 128/256 = 0.5.
  • Modulation: 16-QAM, where each symbol carries 4 coded bits.
  • Channel model: AWGN, which adds white Gaussian noise to the transmitted symbols.
  • Performance metric: Bit Error Rate (BER) plotted versus Eb/N0 in dB.
  • Waterfall behavior: A sharp BER drop appears around 3–4 dB Eb/N0, which is typical for capacity-approaching codes such as Polar codes.
  • High-SNR region: BER rapidly falls below 10−5, indicating successful error correction once the decoder operates above its threshold.
  • Low-SNR region: BER remains high and nearly flat, showing that decoding is unreliable under strong noise.
  • Bit display: The input bits, encoded bits, and decoded bits are shown to allow direct visual verification of Polar decoding correctness.

 

LDPC code Performance

This figure shows the end-to-end performance result of the tutorial script using a 5G NR LDPC code. The simulation follows the same digital communication chain as before: binary data generation, LDPC encoding, QAM mapping, AWGN channel, demapping, LDPC decoding, and BER measurement. The plot illustrates how the decoding performance improves as Eb/N0 increases.

Key points illustrated in the result are as follows

  • Coding scheme: 5G NR LDPC code with information bits K = 128 and codeword length N = 256, resulting in a code rate R = K/N = 128/256 = 0.5.
  • Modulation: 16-QAM, where each modulation symbol carries 4 coded bits.
  • Channel model: AWGN, representing additive white Gaussian noise applied to the transmitted symbols.
  • Performance metric: Bit Error Rate (BER) plotted as a function of Eb/N0 in dB.
  • Waterfall behavior: The BER curve shows a steep drop around 4–5 dB Eb/N0, indicating the decoding threshold of the LDPC code.
  • High-SNR region: Once above the threshold, BER rapidly decreases below 10−5, demonstrating strong error-correction capability.
  • Low-SNR region: At low Eb/N0, BER decreases gradually, reflecting iterative LDPC decoding behavior under noisy conditions.
  • Bit display: The input bits, encoded bits, and decoded bits are shown, allowing direct inspection of LDPC decoding correctness.

 

Uncoded (no channel coding) Performance

This figure shows the end-to-end performance result of the tutorial script for the uncoded case (i.e, No channel coding). The simulation uses the same mapper, channel, and demapper chain as the coded cases, but skips channel coding entirely. It serves as a baseline reference to highlight the coding gain provided by Polar and LDPC codes. The plot shows how the Bit Error Rate (BER) improves as Eb/N0 increases.

Key points illustrated in the result are as follows

  • Coding scheme: Uncoded transmission with code rate R = 1, meaning there is no redundancy added before modulation.
  • Modulation: 16-QAM, where each symbol carries 4 information bits directly.
  • Channel model: AWGN, which adds white Gaussian noise to the transmitted symbols.
  • Performance metric: Bit Error Rate (BER) plotted versus Eb/N0 in dB.
  • BER behavior: The BER decreases smoothly with increasing Eb/N0, without a sharp waterfall region, which is characteristic of uncoded modulation.
  • High-SNR requirement: Very high Eb/N0 values (around 10–12 dB) are required to achieve BER levels below 10−5.
  • Comparison baseline: This curve provides a clear reference for evaluating the coding gain achieved by Polar and LDPC codes at the same modulation order.
  • Bit display: The input bits and decoded bits are directly compared, since encoded bits are identical to input bits in the uncoded case.

Source Code Overview

Even though I no longer need to describe every single line of code in the age of AI, I still think it is valuable to write down some key points. This is not to show off the code itself. It is to record the intention behind the script. I want to clarify what I was trying to do, what kind of idea I had in mind, and what kind of problems this script is designed to solve. This allows the reader to connect the final result with the original design goal. It also helps me later when I come back to this code after a long time and forget my own thinking process.

You may not need all of these details if your only goal is to understand the output of the script. For simple usage, you can often treat the script as a black box. You run it. You look at the result. You move on. In many cases this is enough. However, if you want to modify, revise, or extend the script for your own purpose, the situation changes. You would need to know which part of the code is doing what. You would need to know which parameters control which behavior. You would also need to know what kind of assumptions I made when I first wrote the code. In that case, a clear description of the code is not a luxury. It becomes a kind of map.

One of the best ways to learn anything related to programming is still very old-fashioned. You break it and then you fix it. You change a small part of the script and see what goes wrong. You check the error. You adjust. You run it again. This loop may look inefficient at first, but it forces your brain to connect cause and effect inside the code. So my intention with these explanations is not just to document the script. It is to give you enough context so that you can safely break it, understand why it broke, and then fix it in a way that matches your own idea. This process is painful sometimes, but it is also the part that makes the knowledge stick to your brain.

Key Features

  • 5G FEC Code Support: Polar 5G and LDPC 5G encoding/decoding according to 3GPP specifications
  • 3GPP-Compliant Calculations: Automatic calculation of Base Graph (BG), Lifting Size (Zc), and Set Index (i_LS) from 3GPP TS 38.212
  • Real-time BER Simulation: Interactive BER vs. Eb/N0 performance curves with configurable parameters
  • Auto Sweep Mode: Automated SNR sweep with automatic stopping when BER < 10-6
  • Bit-Level Visualization: Display of information bits, encoded bits (with info/parity separation), and decoded bits with error highlighting
  • Detailed Code Parameters: Comprehensive display of LDPC and Polar code parameters including puncturing, effective code rates, and P(i,j) shift values matrix
  • Multi-Tab Interface: Organized GUI with Main Output, Detailed Info, and Debug Output tabs
  • Modulation Schemes: Support for QPSK, 16-QAM, 64-QAM, and 256-QAM

What is Implemented ?

Followings are the features that I fully implemented (hopefully :)

Feature

Description

3GPP Reference

Polar 5G Encoding/Decoding

Polar code encoding and SCL (Successive Cancellation List) decoding

TS 38.212 Section 5.3.1

LDPC 5G Encoding/Decoding

LDPC code encoding and iterative BP decoding

TS 38.212 Section 5.3.2

Base Graph Selection

Automatic BG1/BG2 selection based on Transport Size (A) and Code Rate (R)

TS 38.212 Section 5.3.2.1

Lifting Size Calculation

Variable kb for BG2 based on code block size B

TS 38.212 Section 5.3.2.2

Set Index (i_LS) Lookup

Mapping of Zc to i_LS from Table 5.3.2-2

TS 38.212 Table 5.3.2-2

LDPC Puncturing

First 2*Zc systematic bits are punctured (not transmitted)

TS 38.212

Effective Code Rate

Calculation accounting for punctured bits: Reff = k/(n - 2*Zc)

TS 38.212

P(i,j) Shift Values Matrix

Display of LDPC parity check matrix shift values (if available)

TS 38.212

AWGN Channel

Additive White Gaussian Noise channel model

-

Modulation Schemes

QPSK, 16-QAM, 64-QAM, 256-QAM

-

Soft Demapping

Log-Likelihood Ratio (LLR) calculation using APP demapper

-

BER Calculation

Real-time Bit Error Rate computation

-

Real-time Plotting

Dynamic BER vs. Eb/N0 curves with multiple code configurations

-

Auto Sweep

Automated SNR sweep from -5 to 15 dB with auto-stop at BER < 10-6

-

Bit Display

Visualization of info bits, encoded bits (info/parity colored), decoded bits (errors highlighted)

-

Code Parameter Display

Detailed information including Zc, BG, kb, punctured bits, effective rate

-

3GPP Calculation Display

Step-by-step calculation of BG and Zc from 3GPP specifications

TS 38.212

Comparison with Sionna

Side-by-side comparison of calculated vs. Sionna library values

-

Debug Output Tab

Centralized debug message display

-

Status Bar

Real-time display of Eb/No, Batch#, and BER

-

What is Partially Implemented ?

Feature

Status

Notes

P(i,j) Matrix Display

Conditional

Only available if load_5g_ldpc_graph function is accessible in the Sionna version

Rate Matching

Not implemented

Puncturing is handled, but full rate matching (repetition/puncturing) not implemented

CRC Attachment

Not implemented

CRC is typically added before encoding in 5G systems

What is NOT Implemented ?

Feature

Description

3GPP Reference

CRC (Cyclic Redundancy Check)

CRC attachment before encoding

TS 38.212 Section 5.1

Rate Matching

Full rate matching including repetition and puncturing

TS 38.212 Section 5.4.2

Segmentation

Code block segmentation for large transport blocks

TS 38.212 Section 5.2.2

Interleaving

Bit interleaving for rate matching

TS 38.212

Description of Parameters (Global Variables)

Debug Configuration

Parameter

Type

Default

Description

DEBUG

bool

True

Enable/disable debug print statements. When True, debug messages are printed to both console and Debug Output tab.

Code Configuration

Parameter

Type

Default

Description

METHODS

list

["Polar 5G", "LDPC 5G", "Uncoded"]

Available FEC coding methods

CONSTELLATIONS

dict

{"QPSK": ("qam", 2), "16-QAM": ("qam", 4), "64-QAM": ("qam", 6), "256-QAM": ("qam", 8)}

Modulation schemes mapping to Sionna format

LDPC Lifting Size Sets (3GPP TS 38.212 Table 5.3.2-2)

Parameter

Type

Description

LDPC_LIFTING_SETS

dict

Maps set index (i_LS) to sets of valid lifting sizes. Format: {i_LS: {Zc1, Zc2, ...}}
i_LS=0: {2, 4, 8, 16, 32, 64, 128, 256}
i_LS=1: {3, 6, 12, 24, 48, 96, 192, 384}
i_LS=2: {5, 10, 20, 40, 80, 160, 320}
i_LS=3: {7, 14, 28, 56, 112, 224}
i_LS=4: {9, 18, 36, 72, 144, 288}
i_LS=5: {11, 22, 44, 88, 176, 352}
i_LS=6: {13, 26, 52, 104, 208}
i_LS=7: {15, 30, 60, 120, 240}

GUI Configuration

Parameter

Type

Default

Description

Window Size

str

"1100x800"

Default window geometry (width x height in pixels)

Batch Size

int

10

Default number of codewords per simulation batch

Eb/N0 Range

tuple

(-5, 15)

Eb/N0 slider range in dB

Default Eb/N0

float

5.0

Default Eb/N0 value in dB

Auto Sweep Step

float

0.5

Eb/N0 increment for auto sweep in dB

Auto Sweep Stop BER

float

1e-6

Auto sweep stops when BER < this value

Component Cache

Parameter

Type

Description

CACHE

dict

Caches Sionna components (encoder, decoder, mapper, demapper, channel) to avoid recreation. Key: (method, k, n, constellation_name)

Description of Functions

get_i_ls_from_zc(zc)

Gets the set index (i_LS) for a given lifting size (Zc) based on 3GPP TS 38.212 Table 5.3.2-2.

Parameters:

Parameter

Type

Description

zc

int

Lifting size (Zc)

Returns: int or None - Set index (i_LS) if found, None otherwise

Example:

i_ls = get_i_ls_from_zc(22)  # Returns 5 (22 is in set {11, 22, 44, 88, 176, 352})

calculate_bg_from_3gpp(k, n)

Calculates Base Graph (BG) from 3GPP TS 38.212 Section 5.3.2.1.

Parameters:

Parameter

Type

Description

k

int

Information block size (Transport Size A)

n

int

Codeword length

Returns: str - 'bg1' or 'bg2'

Rules (applied sequentially):

  1. If A ≤ 292 → BG2
  2. Else if A ≤ 3824 and R ≤ 0.67 → BG2
  3. Else if R ≤ 0.25 → BG2
  4. Else → BG1

Where R = k/n (code rate), A = k (transport size).

Example:

bg = calculate_bg_from_3gpp(128, 256)      # Returns 'bg2' (A=128 <= 292)
bg = calculate_bg_from_3gpp(1000, 2000)    # Returns 'bg2' (A=1000 <= 3824, R=0.5 <= 0.67)
bg = calculate_bg_from_3gpp(5000, 10000)   # Returns 'bg1' (A > 3824, R=0.5 > 0.67)

calculate_zc_from_3gpp(k, bg)

Calculates Lifting Size (Zc) from 3GPP TS 38.212 Section 5.3.2.2.

Parameters:

Parameter

Type

Description

k

int

Information block size (K)

bg

str

Base graph ('bg1' or 'bg2')

Returns: tuple(Zc, i_LS, kb) or (None, None, None) if not found

Steps:

  1.   Determine kb:
    • For BG1: kb = 22 (fixed)
    • For BG2: kb is variable based on code block size B = K:
      • If B > 640: kb = 10
      • If 560 < B ≤ 640: kb = 9
      • If 192 < B ≤ 560: kb = 8
      • If B ≤ 192: kb = 6
  2. Kb = min(kb, K)
  3. Find smallest Zc in Table 5.3.2-2 such that Kb × Zc ≥ K

Example:

zc, i_ls, kb = calculate_zc_from_3gpp(128, 'bg2')
# For K=128, BG2: B=128 ≤ 192 → kb=6
# Kb = min(6, 128) = 6
# 6 × Zc ≥ 128 → Zc ≥ 21.33
# Smallest valid Zc = 22 (from set i_LS=5)
# Returns: (22, 5, 6)

get_system_components(method, k, n, constellation_name)

Creates or retrieves cached Sionna components for the specified configuration.

Parameters:

Parameter

Type

Description

method

str

FEC method: "Polar 5G", "LDPC 5G", or "Uncoded"

k

int

Information block size

n

int

Codeword length

constellation_name

str

Modulation scheme: "QPSK", "16-QAM", "64-QAM", or "256-QAM"

Returns: tuple(source, encoder, decoder, mapper, demapper, channel, num_bits_per_symbol)

  • source: BinarySource - Random bit generator
  • encoder: Polar5GEncoder or LDPC5GEncoder or None (for Uncoded)
  • decoder: Polar5GDecoder or LDPC5GDecoder or None (for Uncoded)
  • mapper: Mapper - Constellation mapper
  • demapper: Demapper - Soft demapper (APP)
  • channel: AWGN - AWGN channel model
  • num_bits_per_symbol: int - Bits per symbol (2, 4, 6, or 8)

Caching: Components are cached by key (method, k, n, constellation_name) to avoid recreation.


run_simulation(method, k, n, constellation_name, ebno_db, batch_size)

Runs a single simulation batch and returns BER and bit sequences.

Parameters:

Parameter

Type

Description

method

str

FEC method: "Polar 5G", "LDPC 5G", or "Uncoded"

k

int

Information block size

n

int

Codeword length

constellation_name

str

Modulation scheme

ebno_db

float

Eb/N0 in dB

batch_size

int

Number of codewords to simulate

Returns: dict with keys:

Key

Type

Description

ber

float

Bit Error Rate

spec_eff

float

Spectral efficiency (bps × code rate)

n0

float

Noise power spectral density

coderate

float

Code rate (k/n)

info_bits

np.array

Information bits from first batch (shape: [k])

encoded_bits

np.array

Encoded bits from first batch (shape: [n])

decoded_bits

np.array

Decoded bits from first batch (shape: [k])

received_encoded_bits

np.array

Hard decisions from LLRs before decoding (shape: [n])

Simulation Flow:

  1. Generate information bits (K bits for coded, N bits for uncoded)
  2. Encode (if coded)
  3. Map to constellation symbols
  4. Add AWGN noise
  5. Demap to LLRs
  6. Decode (if coded)
  7. Calculate BER

Note: For LDPC 5G, the encoder applies puncturing (first 2×Zc bits are not transmitted), but the decoder reconstructs all K information bits including punctured ones.


FECPlaygroundApp

Main Tkinter application class for the FEC playground.

Constructor:

app = FECPlaygroundApp(root)

Key Methods:

setup_ui()

Creates and configures the GUI layout including:

  • Control panel with parameter inputs
  • Tabbed interface (Main Output, Detailed Info, Debug Output)
  • Status bar
  • Plot area
run_step()

Executes one simulation step:

  • Runs simulation with current parameters
  • Updates BER plot
  • Updates bit displays (on first batch of each Eb/No point)
  • Updates detailed info panel
  • Updates status bar
  • Handles auto sweep logic
toggle_simulation()

Starts/stops real-time simulation loop.

start_sweep()

Initiates automated SNR sweep from -5 to 15 dB with 0.5 dB steps. Automatically stops when BER < 10^-6 for at least 5 consecutive points.

update_plot_visuals(ebno, ber)

Updates the BER vs. Eb/N0 plot with new data point.

update_bit_displays(res, method, k, n)

Updates the bit display text boxes:

  • Info bits: Binary representation
  • Encoded bits: Info bits (blue) and parity bits (red) with separator
  • Decoded bits: Binary with error bits highlighted (orange)
update_detailed_info(method, k, n)

Updates the Detailed Info tab with:

  • 3GPP specification calculations (BG, Zc, i_LS)
  • Sionna library values for comparison
  • Code parameters (punctured bits, effective rate, etc.)
  • P(i,j) shift values matrix (if available)
debug_print(*args, **kwargs)

Custom print function that writes to both console and Debug Output tab.

clear_debug_output()

Clears the Debug Output tab.

clear_plots()

Clears all BER curves from the plot.


Polar5GEncoder (sionna.phy.fec.polar)

Creates a Polar 5G encoder.

encoder = Polar5GEncoder(k, n)
codeword = encoder(info_bits)  # Shape: [batch, n]

Parameters:

  • k: Information block size
  • n: Codeword length (must be power of 2, n ≥ k)

Polar5GDecoder (sionna.phy.fec.polar)

Creates a Polar 5G decoder with SCL (Successive Cancellation List) algorithm.

decoder = Polar5GDecoder(encoder, dec_type="SCL", list_size=8)
decoded_bits = decoder(llrs)  # Shape: [batch, k]

Parameters:

  • encoder: Polar5GEncoder instance
  • dec_type: Decoder type ("SCL" for list decoding)
  • list_size: List size for SCL decoding (default: 8)

LDPC5GEncoder (sionna.phy.fec.ldpc)

Creates an LDPC 5G encoder.

encoder = LDPC5GEncoder(k, n)
codeword = encoder(info_bits)  # Shape: [batch, n]

Note: The encoder applies puncturing internally (first 2×Zc systematic bits are not in the output).

Internal Attributes (accessed via getattr):

  • _z: Lifting size (Zc)
  • _bg: Base graph ('bg1' or 'bg2')
  • _kb: Information columns (kb)

LDPC5GDecoder (sionna.phy.fec.ldpc)

Creates an LDPC 5G decoder with iterative belief propagation.

decoder = LDPC5GDecoder(encoder, num_iter=20)
decoded_bits = decoder(llrs)  # Shape: [batch, k]

Parameters:

  • encoder: LDPC5GEncoder instance
  • num_iter: Number of BP iterations (default: 20)

Note: The decoder expects LLRs for the full codeword (including punctured positions, which should be set to 0).


Mapper (sionna.phy.mapping)

Maps bits to constellation symbols.

mapper = Mapper("qam", num_bits_per_symbol=4)  # 16-QAM
symbols = mapper(bits)  # Shape: [batch, num_symbols]

Modulation Options:

  • num_bits_per_symbol=2: QPSK
  • num_bits_per_symbol=4: 16-QAM
  • num_bits_per_symbol=6: 64-QAM
  • num_bits_per_symbol=8: 256-QAM

Demapper (sionna.phy.mapping)

Computes Log-Likelihood Ratios (LLRs) from received symbols.

demapper = Demapper("app", "qam", num_bits_per_symbol=4)  # APP demapper for 16-QAM
llrs = demapper(received_symbols, no)  # Shape: [batch, num_bits]

Parameters:

  • "app": A-posteriori probability (soft) demapping
  • "qam": Constellation type
  • num_bits_per_symbol: Bits per symbol

AWGN (sionna.phy.channel)

Additive White Gaussian Noise channel.

channel = AWGN()
noisy_symbols = channel(symbols, no)  # Shape: same as input

Parameters:

  • symbols: Input symbols
  • no: Noise power spectral density (scalar or tensor)

ebnodb2no (sionna.phy.utils)

Converts Eb/N0 in dB to noise power spectral density.

no = ebnodb2no(ebno_db, num_bits_per_symbol=bps, coderate=R)

Parameters:

  • ebno_db: Eb/N0 in dB
  • num_bits_per_symbol: Bits per symbol
  • coderate: Code rate (k/n)

Returns: Noise power spectral density N0