NVIDIA - Sionna   

 

 

 

System Simulation - PBCH Decoding

This note implements a standalone Python program for decoding 5G NR PBCH (Physical Broadcast Channel) symbols and extracting MIB (Master Information Block) information. The tool implements the complete PBCH decoding pipeline including QPSK demodulation, descrambling, rate matching, polar decoding, CRC verification, payload descrambling, and MIB field extraction. It processes exported PBCH symbols from binary files and outputs decoded MIB information including System Frame Number, Subcarrier Spacing, SSB configuration, and PDCCH parameters.

Followings are brief descriptions on each procedure

  • Input: Binary file containing 432 PBCH QPSK symbols (complex float32 format, .fc32 files)
    • Reads complex IQ samples as pairs of 4-byte floats
    • Supports metadata files for automatic parameter detection
    • Can process single files or batch process all files in a directory
  • QPSK Demodulation: Converts QPSK symbols to Log-Likelihood Ratios (LLRs)
    • Uses soft decision demodulation with configurable scaling factor
    • Outputs 864 LLRs from 432 QPSK symbols (2 bits per symbol)
    • LLR values range from -20 to +20 (hard-limited for numerical stability)
  • PBCH Descrambling: Bit-level descrambling using Gold sequence
    • Gold Sequence Generation: Optimized state machine for pseudo-random sequence generation
      • Uses pre-computed initial states for efficiency
      • Supports bit-by-bit and parallel processing modes
      • Follows 3GPP TS 38.211 sequence generation specification
    • Sequence Initialization: Uses Cell ID (Nid) directly as seed (masked to 31 bits)
    • SSB Index Handling: Advances sequence by v × PBCH_NR_E positions where v = ssb_idx & 0x7 (for Lmax=8)
    • Descrambling Method: Multiplies LLRs by -1 when scrambling bit is 1, +1 when bit is 0
    • Outputs 864 descrambled LLRs
  • Rate Matching: Repetition and de-interleaving for polar code rate matching
    • Repetition: Combines repeated LLRs by addition (for E > N case)
    • Sub-block De-interleaving: Applies 3GPP TS 38.212 Section 5.4.1.1 de-interleaving pattern
    • Outputs 512 LLRs for polar decoder input
  • Polar Decoding: Successive Cancellation (SC) decoder for polar codes
    • Frozen Set: 456 frozen bits (positions not carrying information)
    • Information Set: 56 information bits (K=56, payload + CRC)
    • Decoding Algorithm: Successive Cancellation decoder
    • Outputs 56 decoded bits (32 payload + 24 CRC)
  • CRC Verification: CRC-24C check on decoded message
    • Calculates CRC on all 56 bits (32 payload + 24 CRC)
    • Verifies remainder is zero for valid CRC
    • Reports CRC match status
  • Payload Descrambling: Descrambles 32-bit payload using Gold sequence
    • SFN Bit Extraction: Reads 2nd and 3rd LSB of SFN from polar decoder output
    • Sequence Advancement: Advances sequence by M × v positions where M = PBCH_NR_A − 3 = 29 and v is derived from SFN bits
    • Selective Descrambling: Skips positions 0, 6, and 24 (SFN bits that are not scrambled)
    • Outputs 32 descrambled payload bits
  • Payload Unpacking: De-interleaves payload bits to extract MIB fields
    • De-interleaving Pattern: Uses 3GPP TS 38.212 Section 7.1.1 pattern G
    • Bit Extraction: Extracts 24 MIB bits from 32 payload bits using de-interleaving pattern
    • Bit Packing: Packs bits into bytes for MIB field parsing
  • MIB Field Extraction: Parses 24-bit MIB payload into individual fields

Why Not Sionna in this note ?

In this note none of Sionna API is used even though I wanted to use it.

Sionna is not used in this note because its polar decoder fails to decode real-world PBCH signals correctly, producing outputs that do not match what the gNB actually transmitted. When processing captured PBCH symbols from live 5G NR networks, Sionna's Polar5GDecoder consistently fails to decode the MIB payload correctly, resulting in CRC mismatches and incorrect field extraction even when the input LLRs are properly processed through QPSK demodulation, descrambling, and rate matching. The fundamental issue is that Sionna's decoder uses the SCL (Successive Cancellation List) algorithm, which differs from the SSC (Simplified Successive Cancellation) algorithm used in commercial RAN implementations, and Sionna's internal handling of channel allocation, interleaver patterns, and frozen bit positions may not precisely match the 3GPP-compliant patterns required for correct decoding. To ensure accurate decoding of real-world signals, nr_mib_decode.py uses a custom polar decoder (polar_ssc_decoder.py) that implements the exact SSC algorithm and 3GPP-compliant processing patterns, enabling successful MIB extraction from captured PBCH symbols. This custom implementation was necessary because the primary goal is to correctly decode signals transmitted by actual gNBs, not merely to match a reference implementation, and Sionna's decoder was unable to achieve this fundamental requirement.

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.2.43 (system setup)
    • VSCode Version: 1.105.1
    • Commit: 32cfbe848b35d9eb320980195985450f244b3030
    • Date: 2025-12-19T06:06:44.644Z
    • 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
  • AI Model : Auto (as of Dec 22, 2025)
  • AI Chatbot : Gemini Pro, Chat GPT
  • 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  (NOTE : this is the text print with DEBUG=False in the code. You will get the much detailed print when DEBUG=True)

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

PBCH Decoding Test Program

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

 

PBCH directory: /home/jaeku/nvidia/bin/pbch_extracted

Found 1 PBCH file(s)

 

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

Processing: export_pbch_eq.fc32

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

 

[INFO] Metadata File Content:

[INFO] cell_id=500

i_ssb=0

n_hf=0

Lmax=8

num_symbols=432

sample_rate=23040000.0

scs_khz=30.0

[INFO] =========================================

[INFO] MIB Decoding Input Data

[INFO] =========================================

[INFO] PBCH File: /home/jaeku/nvidia/bin/pbch_extracted/export_pbch_eq.fc32

[INFO] Total PBCH Symbols: 432

[INFO] Complete PBCH Symbol Array (all symbols):

[INFO] [(0.707106829,-0.707106709),(0.707106650,-0.707106650),(0.707106829,-0.707106769),(0.707106769,0.707106829),(-0.707106769,-0.707106769),(-0.707106769,0.707106709),(0.707106769,-0.707106829),(-0.707106769,-0.707106709),(0.707106769,-0.707106769),(-0.707106709,-0.707106769),(-0.707106769,-0.707106829),(-0.707106709,-0.707106709),(0.707106709,-0.707106590),(0.707106650,0.707106829),(0.707106888,0.707106829),(-0.707106948,-0.707106769),(0.707106769,0.707106769),(0.707106709,-0.707106829),(0.707106888,0.707106829),(0.707106709,-0.707106769),(-0.707106888,0.707106709),(0.707106829,0.707106829),(-0.707106888,0.707106769),(-0.707106769,-0.707106769),(0.707106888,0.707106829),(0.707106709,0.707106709),(0.707106650,0.707106769),(-0.707106888,0.707106709),(-0.707106769,0.707106709),(-0.707106829,-0.707106829),(0.707106769,-0.707106650),(0.707106769,-0.707106829),(0.707106650,-0.707106769),(-0.707106769,0.707106709),(0.707106709,-0.707106769),(-0.707106829,0.707106888),(-0.707106888,-0.707106829),(0.707106769,0.707106829),(-0.707106650,0.707106769),(0.707106709,-0.707106888),(0.707106769,-0.707106769),(-0.707106769,0.707106888),(-0.707106888,-0.707106769),(0.707106829,0.707106709),(-0.707106829,-0.707106769),(-0.707106769,0.707106829),(0.707106829,0.707106769),(0.707106829,0.707106829),(0.707106590,-0.707106888),(-0.707106769,0.707106829),(0.707106709,0.707106769),(-0.707106650,0.707106829),(0.707106769,0.707106709),(-0.707106769,0.707106769),(0.707106769,-0.707106829),(-0.707106829,-0.707106829),(0.707106769,-0.707106769),(-0.707106829,0.707106709),(-0.707106769,-0.707106829),(0.707106829,0.707106829),(-0.707106829,-0.707106829),(0.707106829,-0.707106769),(0.707106650,0.707106709),(0.707106590,0.707106769),(0.707106888,-0.707106650),(-0.707106709,0.707106888),(0.707106888,0.707106769),(0.707106709,-0.707106829),(0.707106650,-0.707106769),(-0.707106829,-0.707106650),(-0.707106769,-0.707106709),(-0.707106829,-0.707106769),(0.707106769,0.707106769),(0.707106769,0.707106769),(-0.707106769,-0.707106709),(0.707106650,-0.707106829),(0.707106709,-0.707106829),(-0.707106948,0.707106709),(0.707106888,-0.707106769),(-0.707106888,0.707106829),(-0.707106769,-0.707106829),(-0.707106829,0.707106769),(0.707106829,0.707106888),(-0.707106948,-0.707106888),(-0.707106829,0.707106888),(-0.707106829,0.707106888),(0.707106769,0.707106829),(-0.707106829,-0.707106829),(0.707106709,0.707106829),(0.707106769,0.707106709),(-0.707106709,0.707106709),(-0.707106709,-0.707106829),(0.707106769,0.707106888),(0.707106769,-0.707106709),(-0.707106829,0.707106769),(-0.707106829,0.707106769),(0.707106709,0.707106888),(-0.707106829,0.707106709),(0.707106888,-0.707106769),(-0.707106709,-0.707106769),(0.707106829,0.707106829),(0.707106829,0.707106769),(-0.707106769,0.707106709),(0.707106709,0.707106769),(0.707106769,0.707106829),(0.707106829,-0.707106769),(0.707106709,0.707106888),(0.707106888,0.707106769),(-0.707106829,-0.707106888),(0.707106829,0.707106769),(-0.707106769,0.707106829),(0.707106769,0.707106829),(0.707106829,0.707106829),(0.707106829,-0.707106769),(-0.707106829,-0.707106829),(-0.707106769,-0.707106948),(-0.707106769,0.707106709),(0.707106769,0.707106709),(-0.707106769,0.707106709),(0.707106769,0.707106709),(-0.707106709,-0.707106709),(-0.707106829,-0.707106709),(0.707106769,-0.707106829),(0.707106769,0.707106829),(-0.707106709,0.707106888),(0.707106829,0.707106709),(0.707106829,0.707106709),(-0.707106829,0.707106829),(-0.707106769,0.707106769),(0.707106888,-0.707106888),(-0.707106769,0.707106829),(0.707106709,0.707106709),(0.707106769,0.707106709),(0.707106709,-0.707106709),(0.707106829,0.707106769),(-0.707106829,0.707106769),(0.707106888,-0.707106769),(-0.707106769,-0.707106769),(0.707106829,0.707106769),(-0.707106769,-0.707106769),(0.707106769,-0.707106829),(-0.707106948,0.707106948),(-0.707106948,-0.707106769),(0.707106769,0.707106709),(0.707106650,0.707106709),(0.707106709,0.707106709),(0.707106888,0.707106948),(-0.707106829,-0.707106829),(-0.707106829,-0.707106769),(-0.707106709,0.707106650),(0.707106829,-0.707106709),(0.707106709,0.707106829),(-0.707106590,-0.707106829),(0.707106769,-0.707106769),(0.707106769,0.707106829),(0.707106769,-0.707106769),(-0.707106829,-0.707106769),(-0.707106829,0.707106888),(-0.707106769,-0.707106829),(-0.707106769,0.707106769),(0.707106829,0.707106769),(0.707106650,0.707106829),(0.707106829,-0.707106709),(-0.707106769,-0.707106769),(-0.707106769,-0.707106769),(0.707106769,-0.707106769),(-0.707106650,0.707106888),(-0.707106888,0.707106829),(0.707106829,-0.707106769),(0.707106829,-0.707106650),(0.707106709,0.707106709),(-0.707106531,0.707106829),(0.707106769,0.707106769),(-0.707106829,0.707106829),(0.707106769,-0.707106769),(-0.707106709,-0.707106829),(-0.707106769,-0.707106769),(-0.707106829,-0.707106769),(0.707106709,0.707106709),(-0.707106829,-0.707106709),(-0.707106888,0.707106709),(-0.707106948,0.707106829),(-0.707106709,0.707106709),(-0.707106829,0.707106769),(0.707106709,-0.707106709),(0.707106948,-0.707106888),(0.707106829,0.707106769),(-0.707106709,-0.707106769),(0.707106829,0.707106769),(-0.707106650,0.707106709),(-0.707106829,-0.707106650),(0.707106709,-0.707106829),(-0.707106769,-0.707106709),(-0.707106709,0.707106769),(0.707106888,-0.707106888),(-0.707106769,0.707106948),(-0.707106769,-0.707106888),(0.707106769,-0.707106769),(0.707106888,-0.707106709),(-0.707106888,0.707106769),(0.707106709,0.707106829),(0.707106829,0.707106888),(0.707106948,-0.707106769),(-0.707106709,0.707106709),(-0.707106829,0.707106769),(-0.707106709,-0.707106829),(0.707106829,0.707106709),(-0.707106829,-0.707106769),(-0.707106709,0.707106769),(0.707106829,0.707106888),(-0.707106769,-0.707106709),(0.707106650,-0.707106769),(-0.707106709,0.707106829),(-0.707106709,0.707106769),(0.707106650,-0.707106650),(0.707106769,0.707106590),(-0.707106888,-0.707106769),(0.707106769,0.707106829),(-0.707106829,0.707106829),(0.707106709,-0.707106829),(-0.707106829,0.707106888),(-0.707106769,-0.707106769),(0.707106769,0.707106829),(-0.707106769,0.707106650),(0.707106769,0.707106829),(0.707106709,0.707106829),(0.707106769,-0.707106769),(0.707106829,-0.707106888),(0.707106769,-0.707106948),(0.707106829,-0.707106888),(0.707106829,0.707106709),(-0.707106769,-0.707106709),(-0.707106709,-0.707106769),(-0.707106769,-0.707106709),(0.707106709,-0.707106709),(-0.707106829,0.707106769),(-0.707106829,-0.707106888),(-0.707107008,0.707106829),(0.707106829,0.707106948),(0.707106829,-0.707106709),(0.707106888,-0.707106948),(0.707106888,0.707106709),(0.707106769,0.707106829),(-0.707106948,0.707106709),(-0.707106829,0.707106709),(-0.707106829,0.707106769),(-0.707106829,0.707106769),(-0.707106709,0.707106769),(0.707106709,-0.707106709),(-0.707106709,-0.707106769),(-0.707106590,0.707106590),(0.707106650,0.707106709),(0.707106829,0.707106769),(0.707106769,-0.707106829),(-0.707106709,0.707106709),(-0.707106709,0.707106769),(0.707106888,0.707106769),(0.707106769,-0.707106888),(-0.707106769,-0.707106829),(0.707106829,0.707106829),(-0.707106769,0.707106769),(-0.707106769,0.707106769),(0.707106769,0.707106769),(0.707106829,0.707106769),(0.707106709,0.707106769),(0.707106769,-0.707106709),(0.707106650,0.707106829),(0.707106769,0.707106829),(-0.707106709,-0.707106769),(0.707106709,0.707106769),(0.707106709,-0.707106829),(0.707106709,0.707106709),(0.707106829,-0.707106769),(-0.707106769,-0.707106888),(-0.707106829,-0.707106769),(-0.707106709,0.707106709),(-0.707106709,-0.707106769),(-0.707106769,0.707106709),(-0.707106769,-0.707106888),(0.707106829,-0.707106769),(-0.707106769,-0.707106888),(0.707106829,-0.707106888),(0.707106769,-0.707106948),(-0.707106769,0.707106888),(0.707106709,-0.707106769),(-0.707106888,-0.707106650),(0.707106769,0.707106769),(-0.707106709,0.707106709),(0.707106709,0.707106769),(-0.707106769,-0.707106829),(0.707106829,0.707106829),(-0.707106829,0.707106829),(0.707106829,0.707106829),(-0.707106769,-0.707106829),(0.707106769,-0.707106709),(-0.707106769,-0.707106829),(0.707106769,0.707106769),(0.707106829,0.707106829),(0.707106769,-0.707106829),(-0.707106829,0.707106948),(-0.707106829,0.707106888),(0.707106769,-0.707106888),(0.707106769,-0.707106769),(0.707106769,0.707106769),(-0.707106709,0.707106769),(-0.707106769,0.707106709),(-0.707106709,0.707106769),(-0.707106769,0.707106769),(-0.707106769,-0.707106709),(-0.707106650,0.707106769),(0.707106650,-0.707106829),(-0.707106829,0.707106769),(-0.707106769,0.707106709),(-0.707106650,-0.707106769),(-0.707106829,0.707106769),(-0.707106888,0.707106829),(-0.707106769,-0.707106829),(0.707106769,-0.707106829),(-0.707106829,-0.707106709),(0.707106888,0.707106769),(0.707106829,0.707106769),(0.707106829,0.707106829),(0.707106829,0.707106829),(0.707106709,-0.707106709),(0.707106829,-0.707106769),(0.707106769,-0.707106709),(-0.707106829,-0.707106948),(-0.707106769,-0.707106888),(0.707106888,-0.707106709),(-0.707106829,0.707106709),(-0.707106829,0.707106709),(-0.707106590,-0.707106888),(-0.707106769,0.707106829),(0.707106769,-0.707106829),(0.707106829,0.707106769),(-0.707106650,-0.707106769),(0.707106650,0.707106709),(0.707106709,-0.707106769),(-0.707106709,0.707106709),(-0.707106829,0.707106650),(0.707106769,-0.707106769),(-0.707106829,-0.707106829),(-0.707106769,-0.707106829),(0.707106709,-0.707106829),(-0.707106769,0.707106709),(-0.707106709,0.707106709),(0.707106769,-0.707106650),(-0.707106709,0.707106709),(-0.707106709,0.707106829),(-0.707106650,-0.707106709),(-0.707106769,-0.707106769),(-0.707106829,0.707106769),(-0.707106709,0.707106769),(-0.707106769,-0.707106650),(0.707106709,-0.707106769),(0.707106769,-0.707106709),(0.707106709,-0.707106829),(0.707106829,0.707106709),(-0.707106769,-0.707106650),(-0.707106709,-0.707106769),(0.707106769,0.707106769),(-0.707106769,-0.707106829),(-0.707106709,0.707106769),(-0.707106650,0.707106769),(0.707106829,0.707106709),(-0.707106769,0.707106769),(0.707106709,0.707106829),(-0.707106829,0.707106829),(0.707106709,0.707106888),(-0.707106769,-0.707106709),(0.707106769,-0.707106709),(-0.707106769,0.707106650),(-0.707106888,0.707106769),(0.707106769,-0.707106709),(-0.707106769,0.707106769),(0.707106769,0.707106769),(0.707106769,0.707106709),(0.707106769,-0.707106829),(0.707106769,-0.70710676

9),(-0.707106829,0.707106829),(0.707106829,-0.707106829),(-0.707106888,-0.707106829),(-0.707106769,0.707106769),(-0.707106888,-0.707106709),(0.707106769,-0.707106888),(-0.707106769,-0.707106650),(-0.707106888,-0.707106829),(-0.707106709,0.707106709),(-0.707106829,-0.707106709),(-0.707106829,-0.707106829),(0.707106888,-0.707106888),(0.707106829,0.707106888),(-0.707106709,0.707106888),(0.707106709,-0.707106888),(-0.707106709,0.707106888),(0.707106829,0.707106709),(-0.707106829,0.707106829),(-0.707106769,0.707106829),(-0.707106829,0.707106829),(0.707106769,0.707106948),(0.707106769,0.707106829),(0.707106769,0.707106590),(-0.707106709,-0.707106650),(-0.707106709,0.707106888),(0.707106829,0.707106829),(-0.707106888,0.707106769),(-0.707106709,0.707106829),(0.707106709,-0.707106829),(-0.707106709,0.707106829),(-0.707106650,0.707106829),(-0.707106650,0.707106709),(0.707106888,0.707106709),(0.707106709,0.707106829),(0.707106709,0.707106650),(0.707106709,-0.707106829),(0.707106709,0.707106650),(-0.707106829,0.707106709),(-0.707106709,-0.707106829),(0.707106709,0.707106888),(0.707106888,0.707106769),(0.707106829,-0.707106769),(-0.707106769,0.707106769),(0.707106888,0.707106888),(-0.707106769,0.707106769),(-0.707106769,-0.707106829),(-0.707106709,0.707106769),(0.707106888,0.707106829),(0.707106709,0.707106829),(-0.707106769,0.707106769),(-0.707106829,0.707106709),(0.707106829,0.707106888),(0.707106709,0.707106829)]

 

[INFO] Metadata File: /home/jaeku/nvidia/bin/pbch_extracted/export_pbch_metadata.txt

[INFO] Metadata Parameters:

[INFO]   Cell ID (N_id): 500

[INFO]   SSB Index (i_ssb): 0

[INFO]   Half-frame (n_hf): 0

[INFO]   L_max: 8

[INFO] =========================================

 

 

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

Decoded MIB Information:

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

payload=210504 sfn_lsb=14 ssb_idx=0 k_ssb_msb=0 hrf=0

 

MIB Fields:

  System Frame Number: 270

  Subcarrier Spacing Common: 30 kHz

  SSB Subcarrier Offset: 0

  DMRS Type A Position: pos2

  PDCCH Config SIB1:

    Control Resource Set Zero (coreset0_idx): 10

    Search Space Zero (ss0_idx): 0

  Cell Barred: notBarred

  Intra-Freq Reselection: allowed

 

Raw Payload (32 bits): 0x0000000100000001010000010000000001000000000100000001000100000000

 

[INFO] =========================================

[INFO] MIB Decoding Final Output

[INFO] =========================================

[INFO] Decoding Status: SUCCESS

[INFO] Decoded Payload (24 bits): 210504

[INFO] System Frame Number: 270

[INFO] Subcarrier Spacing Common: 30 kHz

[INFO] SSB Subcarrier Offset: 0

[INFO] SSB Index: 0

[INFO] Half-frame Indicator: 0

[INFO] DMRS Type A Position: pos2

[INFO] PDCCH Config SIB1:

[INFO]   Control Resource Set Zero (coreset0_idx): 10

[INFO]   Search Space Zero (ss0_idx): 0

[INFO] Cell Barred: notBarred

[INFO] Intra-Freq Reselection: allowed

[INFO] Raw Payload (32 bits): 0x0000000100000001010000010000000001000000000100000001000100000000

[INFO] =========================================

 

 

✓ SUCCESS: export_pbch_eq.fc32

 

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

 

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

Summary

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

Total files processed: 1

Successful: 1

Failed: 0

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

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

  • Complete PBCH Decoding Pipeline: Implements all steps from QPSK symbols to MIB information
    • QPSK Demodulation: Soft decision demodulation with LLR computation
    • Gold Sequence Generation: Optimized state machine implementation with pre-computed initial states
    • Bit-level Descrambling: Accurate LLR descrambling using Gold sequence state machine
    • Rate Matching: Repetition and sub-block de-interleaving per 3GPP TS 38.212
    • Polar Decoding: Successive Cancellation decoder for polar codes
    • CRC Verification: CRC-24C check with detailed verification reporting
    • Payload Processing: Descrambling and de-interleaving for MIB extraction
    • MIB Parsing: Complete field extraction with human-readable output
  • 3GPP-Compliant Implementation: Follows 3GPP specifications for all processing steps
    • TS 38.211: PBCH scrambling sequence generation and structure
    • TS 38.212: Rate matching, polar coding, and payload de-interleaving
    • TS 38.331: MIB field definitions and bit positions
  • Automatic Metadata Detection: Reads metadata files for automatic parameter configuration
    • Metadata File Format: Text files with key-value pairs (cell_id, ssb_idx, n_hf, Lmax)
    • Automatic Discovery: Searches for metadata files matching PBCH file names
    • Fallback to Manual: Supports manual parameter specification if metadata unavailable
  • Batch Processing: Processes multiple PBCH files in a directory automatically
    • Directory Scanning: Automatically finds all *_pbch_eq.fc32 files
    • Metadata Matching: Matches each file with corresponding metadata file
    • Summary Report: Provides summary of successful and failed decodings
  • Comprehensive Debug Output: Detailed step-by-step processing information
    • Input Data Display: Shows complete PBCH symbol array
    • LLR Sequences: Displays LLR values at each processing stage
    • Sequence Generation: Shows Gold sequence bits for verification
    • Processing Statistics: Reports min/max/mean values at each step
    • Field Extraction: Shows bit-level extraction details

Fully Implemented

Feature

Description

3GPP Reference

QPSK Demodulation

Soft decision demodulation with LLR computation

TS 38.211 Section 7.4.3

Gold Sequence Generation

Optimized state machine with pre-computed initial states

TS 38.211 Section 5.2.1

PBCH Descrambling

Bit-level descrambling using Gold sequence

TS 38.211 Section 7.3.3.1

Rate Matching

Repetition and sub-block de-interleaving

TS 38.212 Section 5.4.1

Polar Decoding

Successive Cancellation decoder

TS 38.212 Section 5.3

CRC-24C Verification

CRC check on decoded message

TS 38.212 Section 5.1

Payload Descrambling

Gold sequence descrambling with SFN-based advancement

TS 38.212 Section 7.1.2

Payload Unpacking

De-interleaving pattern G application

TS 38.212 Section 7.1.1

MIB Field Extraction

Complete MIB field parsing

TS 38.331 Section 6.2.2

Metadata File Reading

Automatic parameter detection from metadata files

-

Batch Processing

Automatic processing of multiple files

-

Debug Output

Comprehensive step-by-step processing information

-

Partially Implemented

  • Polar Decoding: Currently implements Successive Cancellation (SC) decoder only
    • Not Implemented: Successive Cancellation List (SCL) decoder for improved performance
    • Not Implemented: CRC-aided polar decoding
    • Note: SC decoder is sufficient for PBCH decoding (K=56, N=512)

Not Implemented

  • Advanced Polar Decoders: Not supported
    • SCL decoder not implemented
    • CRC-aided decoding not implemented
    • SC decoder is sufficient for PBCH decoding
  • GUI Interface: Command-line only (no graphical user interface)
  • Real-time Processing: Batch processing only (no streaming mode)
  • Error Recovery: No automatic retry or error correction beyond CRC check
  • Multiple SSB Index Search: Processes a single SSB index (no blind search for correct SSB index)

Description of Parameters (Global Variables)

Command-Line Arguments

Parameter

Type

Description

Default

input_file

string

Path to PBCH symbol file (.fc32 format)

Required (or auto-detect)

cell_id

integer

Cell ID (Nid, 0–1007)

From metadata or required

ssb_idx

integer

SSB index (issb, 0–7)

From metadata or 0

n_hf

integer

Half-frame indicator (0 or 1)

From metadata or 0

offset

integer

Symbol offset in file

0

count

integer

Number of symbols to read

432 (PBCH_NR_M)

Metadata File Format

Metadata files are text files with key-value pairs (one per line):

cell_id=500
ssb_idx=0
n_hf=0
Lmax=8
                

Metadata File Naming Convention:

  • For file export_pbch_eq.fc32, searches for:
    1. export_pbch_metadata.txtfc32 (filename + extension)
    2. export_pbch_metadata.txt (filename + _metadata.txt)
    3. export_pbch_eq_metadata.txt (filename with _metadata.txt inserted)

PBCH Constants

Constant

Value

Description

PBCH_NR_M

432

Number of QPSK symbols

PBCH_NR_E

864

Number of encoded bits after rate matching

PBCH_NR_N

512

Polar code block size

PBCH_NR_A

32

Payload size (24 MIB bits + 8 overhead bits)

PBCH_NR_K

56

Payload + CRC size (32 + 24)

Description of Functions

Core Decoding Functions

decode_pbch(pbch_symbols, cell_id, ssb_idx=0, n_hf=0, Lmax=8)

Main PBCH decoding function implementing the complete decoding pipeline.

Parameters:

  • pbch_symbols (numpy.ndarray): Array of 432 complex QPSK symbols
  • cell_id (int): Cell ID (Nid, 0–1007)
  • ssb_idx (int): SSB index (issb, 0–7), default 0
  • n_hf (int): Half-frame indicator (0 or 1), default 0
  • Lmax (int): Maximum number of SSB indices (4, 8, or 64), default 8

Returns:

  • dict: Decoded MIB information dictionary
    • payload: 24-bit MIB payload (hex string)
    • sfn_lsb: System Frame Number LSB (6 bits)
    • ssb_idx: SSB index
    • k_ssb_msb: SSB subcarrier offset MSB (4 bits)
    • hrf: Half-frame indicator
    • scs_common: Subcarrier spacing common (15 or 30 kHz)
    • dmrs_type_a_pos: DMRS Type A position (pos2 or pos3)
    • coreset0_idx: Control Resource Set Zero index
    • ss0_idx: Search Space Zero index
    • cell_barred: Cell barred status
    • intra_freq_reselection: Intra-frequency reselection allowed status

Processing Steps:

  1. QPSK demodulation (symbols → LLRs)
  2. PBCH descrambling (bit-level, Gold sequence)
  3. Rate matching (repetition and de-interleaving)
  4. Polar decoding (SC decoder)
  5. CRC verification (CRC-24C check)
  6. Payload descrambling (Gold sequence with SFN-based advancement)
  7. Payload unpacking (de-interleaving pattern G)
  8. MIB field extraction

qpsk_demodulate(symbols)

Performs soft decision QPSK demodulation, converting QPSK symbols to Log-Likelihood Ratios (LLRs).

Parameters:

  • symbols (numpy.ndarray): Array of complex QPSK symbols (432 symbols)

Returns:

  • numpy.ndarray: Array of 864 LLRs (2 bits per symbol, hard-limited to ±20)

Algorithm:

  • Computes LLRs for I and Q components separately
  • Uses scaling factor SCALE_BYTE_CONV_QPSK = 20.0 for LLR quantization
  • Hard-limits LLRs to range [-20, +20] for numerical stability

pbch_descramble_llr(cfg, ssb_idx, llr_in, llr_out)

Performs bit-level PBCH descrambling using Gold sequence.

Parameters:

  • cfg (dict): Configuration dictionary with N_id (Cell ID)
  • ssb_idx (int): SSB index (issb, 0–7)
  • llr_in (numpy.ndarray): Input LLRs (864 values)
  • llr_out (numpy.ndarray): Output array for descrambled LLRs (864 values)

Returns:

  • int: 0 on success

Algorithm:

  • Initializes Gold sequence with N_id & 0x7FFFFFFF
  • Advances sequence by v × PBCH_NR_E where v = ssb_idx & 0x7
  • Descrambles by multiplying LLRs by -1 (bit=1) or +1 (bit=0)

rate_matching_pbch(llr_in, llr_out)

Performs rate matching for PBCH.

Parameters:

  • llr_in (numpy.ndarray): Input LLRs (864 values)
  • llr_out (numpy.ndarray): Output rate-matched LLRs (512 values)

Algorithm:

  • Repetition: Combines repeated LLRs by addition for E > N
  • Sub-block De-interleaving: 3GPP TS 38.212 Section 5.4.1.1
  • Negation: Negates all LLRs to match reference behavior

polar_decode_pbch(llr_in, bits_out)

Performs polar decoding using Successive Cancellation (SC).

Algorithm:

  • 456 frozen bit positions
  • 56 information bits (K=56)
  • Successive Cancellation decoder
  • Channel allocation and interleaver deinterleaving

check_crc24c(bits)

Verifies CRC-24C on decoded message.

  • Polynomial: 0x1B2B117
  • Returns true if remainder is zero

pbch_payload_descramble(cfg, b, a)

Descrambles 32-bit payload using Gold sequence with SFN-based advancement.

  • Extracts SFN bits from positions 6 and 24
  • Computes v = 2·b[24] + b[6]
  • Advances sequence by M × v, where M = 29
  • Skips positions 0, 6, and 24 during descrambling

pbch_msg_unpack(cfg, a, msg)

Unpacks descrambled payload to extract MIB bits.

  • Applies de-interleaving pattern G (TS 38.212 Section 7.1.1)
  • Extracts 24 MIB bits from 32 payload bits
  • Packs bits into bytes and stores in msg['payload']

Gold Sequence Generation

GoldSequenceState

Class implementing an optimized Gold sequence state machine for pseudo-random sequence generation.

Methods:

  • init(seed): Initialize sequence state from seed value (starts from position 1600)
  • init_from_zero(seed): Initialize sequence state starting from position 0
  • advance(n): Advance sequence state by n bits (bit-by-bit advancement)
  • apply_to_llrs(llr_in, llr_out, length): Apply sequence to LLRs (parallel processing in 24-bit chunks)
  • apply_to_bits(bits_in, bits_out, length): Apply sequence to bits (XOR operation)

Key Features:

  • Pre-computed initial states for efficiency
  • Supports bit-by-bit and parallel processing modes
  • Optimized state machine implementation
  • Follows 3GPP TS 38.211 Section 5.2.1 specification

File I/O Functions

read_fc32_file(filename, offset=0, count=0)

Reads PBCH symbols from a binary file in complex float32 format.

Parameters:

  • filename (str): Path to .fc32 file
  • offset (int): Symbol offset in file, default 0
  • count (int): Number of symbols to read (0 = read all), default 0

Returns:

  • numpy.ndarray: Array of complex symbols

File Format:

  • Binary file with pairs of 4-byte floats (I, Q)
  • Little-endian byte order
  • Total size: count × 2 × 4 bytes (if count > 0)

read_metadata_file(filename)

Reads metadata file for automatic parameter detection.

Parameters:

  • filename (str): Path to metadata file

Returns:

  • dict: Dictionary with keys cell_id, ssb_idx, n_hf, Lmax

File Format:

  • Text file with key-value pairs (one per line)
  • Format: key=value
  • Supported keys: cell_id, ssb_idx, n_hf, Lmax

Batch Processing Functions

process_single_file(filename, offset=0, count=PBCH_NR_M)

Processes a single PBCH file with automatic metadata detection.

Parameters:

  • filename (str): Path to PBCH file
  • offset (int): Symbol offset, default 0
  • count (int): Number of symbols to read, default 432

Returns:

  • bool: True on success, False on failure

Algorithm:

  1. Searches for metadata file matching PBCH file name
  2. Reads metadata if found, otherwise uses default parameters
  3. Reads PBCH symbols from file
  4. Calls decode_pbch() with detected parameters
  5. Displays decoded MIB information

Decoding Pipeline

Step-by-Step Processing

  1. File Reading (Step 0)
    • Reads 432 PBCH QPSK symbols from binary file (.fc32, complex float32)
    • Debug Output: Displays complete PBCH symbol array (real/imaginary values)
    • Format: (real,imag) pairs with 9-decimal precision
    • Reads metadata file for automatic parameter detection (if available)
      • Searches metadata files matching PBCH filename patterns
      • Extracts cell_id, ssb_idx, n_hf, Lmax
    • Configuration Display: Nid, SSB index, half-frame indicator, Lmax, symbol count
  2. QPSK Demodulation (Step 1)
    • Converts 432 QPSK symbols to 864 LLRs (2 bits per symbol)
    • Symbol Statistics: min / max / mean magnitude
    • Symbol Display: First 10 symbols (6-decimal precision)
    • Soft decision demodulation with SCALE_BYTE_CONV_QPSK = 20.0
    • LLRs hard-limited to [-20, +20]
    • LLR Statistics: min / max / mean
    • LLR Display: First 100 values and full 864-value sequence
    • Output: 864 LLRs for descrambling
  3. PBCH Descrambling (Step 2)
    • Initialization: Computes c_init_pbch = 211·Nid + 26·ssb_idx + n_hf
    • Gold Sequence Generation
      • Displays first 20 and first 100 scrambling bits
      • Uses Nid & 0x7FFFFFFF as seed
    • SSB Index Handling
      • v = ssb_idx & 0x7 (for Lmax=8)
      • Sequence advanced by v × PBCH_NR_E
    • Input/Output Comparison: First 10 input LLRs, sequence bits, output LLRs
    • Gold Sequence Recovery
      • Recovers scrambling bits from input/output LLR comparison
      • Displays recovery details for first 10 positions
      • Reports ambiguous positions and match count
    • Descrambling Rule: Multiply LLR by -1 (bit=1) or +1 (bit=0)
    • Statistics: min / max / mean of descrambled LLRs
    • Reference Comparison: Full-sequence match/mismatch reporting
  4. Rate Matching and BCH Decoding (Step 3)
    • Displays first and last 20 descrambled LLRs
    • Repetition: 864 → 512 LLRs (factor ≈ 1.688)
    • Combines repetitions using y[k_N] += e[k], k_N = k % N
    • Sub-block De-interleaving: TS 38.212 §5.4.1.1
    • Negation: Negates all LLRs (reference behavior)
    • Statistics: min / max / mean of rate-matched LLRs
    • Output: 512 LLRs for polar decoding
  5. Post-Polar Processing (Step 4)
    • Polar Decoding
      • Frozen set: 456 bits
      • Information set: 56 bits (payload + CRC)
      • Algorithm: Successive Cancellation (SC)
    • Displays decoded bits and hexadecimal representation
    • Output: 56 decoded bits (32 payload + 24 CRC)
  6. CRC Verification (Step 4.1)
    • CRC-24C polynomial: 0x1B2B117
    • Step-by-step CRC calculation debug output
    • Reports remainder and match status (PASS / FAIL)
  7. PBCH Payload Descrambling (Step 4.2)
    • Extracts SFN bits from positions 6 and 24
    • Computes v = 2·b[24] + b[6]
    • Advances Gold sequence by 29 × v
    • Skips positions 0, 6, and 24
    • Output: 32 descrambled payload bits
  8. PBCH Payload Unpacking (Step 4.3)
    • Uses pattern G (TS 38.212 §7.1.1)
    • Extracts 24 MIB bits from 32 payload bits
    • Packs bits into bytes
    • Output: 24 MIB bits
  9. MIB Field Parsing (Step 4.4)
    • Parses 24-bit MIB per TS 38.331
    • Extracts SFN, SCS, kSSB, DMRS position, CORESET0, SS0, cell barred, reselection
    • Output: Complete MIB information dictionary