|
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):
- If A ≤ 292 → BG2
- Else if A ≤ 3824 and R ≤ 0.67 → BG2
- Else if R ≤ 0.25 → BG2
- 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:
-
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
Kb = min(kb, K)
- 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:
- Generate information bits (K bits for coded, N bits for uncoded)
- Encode (if coded)
- Map to constellation symbols
- Add AWGN noise
- Demap to LLRs
- Decode (if coded)
- 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
|
|