NVIDIA - Sionna   

 

 

 

IQ generation - Downlink : SSB

For this note, the script provides a comprehensive 5G NR SSB (Synchronization Signal Block) generator that creates time-domain IQ samples containing fully encoded SSB bursts. The tool generates PSS (Primary Synchronization Signal), SSS (Secondary Synchronization Signal), PBCH (Physical Broadcast Channel), and PBCH DMRS (Demodulation Reference Signal) sequences according to 3GPP TS 38.211 and TS 38.212 specifications. It provides an interactive GUI for configuring SSB parameters, MIB (Master Information Block) content, and exporting binary IQ files suitable for testing SSB detection and decoding tools.

NOTE : Although this note (python script) can be seen as a visualization extension of Resource Grid - Downlink : SSBy, internally it is a major upgrade that changes the tool from a lightweight resource-grid viewer into a full 3GPP-compliant SSB generator: the older script mainly focuses on frequency-domain grid visualization and uses simplified or placeholder PBCH/DMRS content (often random QPSK or seed-based sequences) with limited configurability, while the newer script implements the complete PBCH encoding chain per TS 38.211/38.212 (MIB 24-bit packing, PBCH 32-bit message packing, Gold-sequence scrambling, CRC-24C matching srsRAN, polar interleaving, frozen-set allocation, systematic polar encoding with N=512, sub-block interleaving, rate matching to 864 bits, final scrambling, and QPSK mapping to 432 symbols), generates 3GPP-accurate Gold-based PBCH DMRS, adds full OFDM modulation (IFFT + cyclic prefix) to produce time-domain IQ samples for binary export and downstream detection/decoding, provides a full MIB configuration UI covering all key MIB information elements, moves toward a more self-contained architecture for core grid/encoding logic.

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

  • Input: GUI configuration
    • SSB parameters
      • SSB Case
      • SSB SCS
      • PDSCH SCS
      • Channel BW
      • Cell ID
      • Lmax
      • SSB TX Bitmap
    • MIB parameters
      • SFN
      • Subcarrier Spacing Common
      • SSB Subcarrier Offset
      • DMRS Position
      • CORESET0 Index
      • SS0 Index
      • Cell Barred
      • Intra-Freq Reselection
    • Export parameters
      • Sample Rate
      • Duration
      • Number of Symbols
      • FFT Size
      • CP Length
  • Processing Steps
    • MIB Payload Encoding: Pack 24 MIB information elements into binary payload
    • PBCH Message Packing: Combine MIB payload (24 bits) with SSB index, half-frame, kSSB MSB (32 bits total)
    • Payload Scrambling: Apply Gold sequence-based scrambling initialized with ncell_id
    • CRC-24C Addition: Compute 24-bit CRC using byte-based table lookup (polynomial 0x1B2B117)
    • Polar Interleaving: Apply 164-element interleaver pattern for K = 56
    • Channel Allocation: Compute frozen bit positions for polar code (K = 56, N = 512)
    • Polar Encoding: Perform systematic polar encoding (output: 512 bits)
    • Sub-block Interleaving: Apply BLK_INTERLEAVER_9 pattern (864 elements)
    • Rate Matching: Puncture to 864 bits (PBCH_NR_E)
    • PBCH Scrambling: Apply Gold sequence-based bit-level scrambling
    • QPSK Modulation: Map 864 scrambled bits to 432 QPSK symbols
    • PSS Sequence Generation: Generate 127 BPSK symbols using m-sequence (polynomial x7 + x4 + 1)
    • SSS Sequence Generation: Generate 127 BPSK symbols using two m-sequences with cyclic shifts
    • PBCH DMRS Sequence Generation: Generate 144 QPSK symbols using Gold sequence
    • SSB Mask Generation: Create masks for PSS, SSS, PBCH, and PBCH DMRS positions
    • Resource Grid Construction: Map sequences to SSB resource grid (4 symbols × 240 subcarriers)
    • Full Resource Grid Assembly: Place SSB bursts at calculated positions based on SSB Case and Lmax
    • Visualization: Update GUI tabs (Resource Grid, Structure, Time Pattern, Constellation)
    • OFDM Modulation (for export): Apply IFFT and add cyclic prefix to convert frequency-domain to time-domain
    • Binary Export: Convert time-domain IQ samples to interleaved I/Q float32 format and write to .bin file
    • Metadata Export: Generate JSON metadata file with configuration parameters
  • Output
    • Binary IQ file (.bin format: 4-byte float I/Q pairs, complex64)
    • Metadata file (.meta format: JSON with all configuration parameters)
    • Interactive visualizations (Resource Grid, SSB Structure, Time Pattern, Constellation tabs)

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: 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
  • AI Model : Opus 4.5 (as of Dec 8, 2025) and GPT 5.1 Codex Max(as of Dec 8, 2025)
  • 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

2025-12-25 17:27:52.673165: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.

2025-12-25 17:27:52.676614: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.

2025-12-25 17:27:52.801531: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.

To enable the following instructions: AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.

2025-12-25 17:27:54.575803: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.

2025-12-25 17:27:54.577087: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.

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

SSB Resource Grid Configuration

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

SSB Case:                 B

SSB Subcarrier Spacing:   30 kHz

L_max:                    8

SSB TX Bitmap:            11111111

SSBs Transmitted:         8

SSB Symbol Positions:     [4, 8, 16, 20, 32, 36, 44, 48]

SSB Indices (bitmap):     [0, 1, 2, 3, 4, 5, 6, 7]

offsetToPointA (RB@15k):  10

k_SSB (SC@15k):           0

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

Channel Bandwidth:        20 MHz

Max RBs in Channel:       51

FFT Size:                 2048

Guard Carriers:           718 (left), 718 (right)

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

Half Frame Duration:      5.0 ms

Slot Duration:            0.5 ms

Slots in Half Frame:      10

Total OFDM Symbols:       140

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

SSB Size:                 20 RBs x 4 symbols

SSB Offset (RB):          5

SSB Start Subcarrier:     60

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

Cell ID:                  500

N_ID^(1):                 166

N_ID^(2):                 2

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

[DEBUG] create_ssb_masks: n_cell_id=500, v_bar=0

[DEBUG] create_ssb_masks: ssb_scs_ratio=1.0, dmrs_spacing=4, v_bar_scaled=0

 

SSB Resource Element Statistics:

  PSS REs:           1016

  SSS REs:           1016

  PBCH REs:          3456

  PBCH DMRS REs:     1152

  Total SSB REs:     6640

  REs per SSB:       960

 

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

SSB Configuration Summary

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

SSB Case:                      B

Subcarrier Spacing:            30 kHz

L_max:                         8

SSB TX Bitmap:                 11111111

SSBs Transmitted:              8

SSB Starting Symbols:          [4, 8, 16, 20, 32, 36, 44, 48]

SSB Indices (bitmap order):    [0, 1, 2, 3, 4, 5, 6, 7]

offsetToPointA (RB@15k):       10

k_SSB (SC@15k):                0

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

Time Domain:

  Half Frame Duration:         5.0 ms

  Slots in Half Frame:         10

  Symbols per Slot:            14

  Total Symbols (5ms):         140

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

Frequency Domain:

  Channel Bandwidth:           20 MHz

  Max RBs in Channel:          51

  SSB Size:                    20 RBs (240 subcarriers)

  SSB Start RB:                5

  SSB Start Subcarrier:        60

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

SSB Components (per burst):

  PSS:                         127 subcarriers (Symbol 0)

  SSS:                         127 subcarriers (Symbol 2)

  PBCH:                        3 symbols with DMRS (every 4th SC)

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

 

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

Launching SSB Resource Grid Viewer...

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

[DEBUG] SSB Position Calculation:

  SSB Case: B

  SSB SCS: 30 kHz

  PDSCH SCS: 30 kHz

  L_max: 8

  first_symbols_ssb_scs: [4, 8, 16, 20]

  period_ssb_scs: 28

  frequency_range_key from params: None

  frequency_range label from params: NOT FOUND

  WARNING: Using fallback calculation (n_values not found)

  Fallback n_values: [0, 1]

    n=0, first_sym=4 -> sym=4 + 28*0 = 4

    n=0, first_sym=8 -> sym=8 + 28*0 = 8

    n=0, first_sym=16 -> sym=16 + 28*0 = 16

    n=0, first_sym=20 -> sym=20 + 28*0 = 20

    n=1, first_sym=4 -> sym=4 + 28*1 = 32

    n=1, first_sym=8 -> sym=8 + 28*1 = 36

    n=1, first_sym=16 -> sym=16 + 28*1 = 44

    n=1, first_sym=20 -> sym=20 + 28*1 = 48

  SSB positions at SSB SCS (30 kHz): [4, 8, 16, 20, 32, 36, 44, 48]

  SSB positions (using native SSB SCS, not converted to PDSCH SCS): [4, 8, 16, 20, 32, 36, 44, 48]

  Note: SSB positions are defined at SSB SCS (30 kHz) and remain unchanged

[DEBUG] Generating DMRS sequences for 8 transmitted SSBs

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=0

  term1 = (0+1) * ((500//4)+1) = 126

  term2 = (0+1) = 1

  term3 = 500 % 4 = 0

  c_init = 2^11*126 + 2^6*1 + 0 = 258112

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=136, mean=0.472

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=1

  term1 = (1+1) * ((500//4)+1) = 252

  term2 = (1+1) = 2

  term3 = 500 % 4 = 0

  c_init = 2^11*252 + 2^6*2 + 0 = 516224

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=129, mean=0.448

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=2

  term1 = (2+1) * ((500//4)+1) = 378

  term2 = (2+1) = 3

  term3 = 500 % 4 = 0

  c_init = 2^11*378 + 2^6*3 + 0 = 774336

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=136, mean=0.472

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=3

  term1 = (3+1) * ((500//4)+1) = 504

  term2 = (3+1) = 4

  term3 = 500 % 4 = 0

  c_init = 2^11*504 + 2^6*4 + 0 = 1032448

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=147, mean=0.510

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=4

  term1 = (4+1) * ((500//4)+1) = 630

  term2 = (4+1) = 5

  term3 = 500 % 4 = 0

  c_init = 2^11*630 + 2^6*5 + 0 = 1290560

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=150, mean=0.521

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=5

  term1 = (5+1) * ((500//4)+1) = 756

  term2 = (5+1) = 6

  term3 = 500 % 4 = 0

  c_init = 2^11*756 + 2^6*6 + 0 = 1548672

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=147, mean=0.510

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=6

  term1 = (6+1) * ((500//4)+1) = 882

  term2 = (6+1) = 7

  term3 = 500 % 4 = 0

  c_init = 2^11*882 + 2^6*7 + 0 = 1806784

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=142, mean=0.493

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=7

  term1 = (7+1) * ((500//4)+1) = 1008

  term2 = (7+1) = 8

  term3 = 500 % 4 = 0

  c_init = 2^11*1008 + 2^6*8 + 0 = 2064896

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=149, mean=0.517

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

 

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

[DEBUG] PBCH Data Summary for All SSBs

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

 

SSB Index 0:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 0

      advance: 0 bits

 

SSB Index 1:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 1

      advance: 864 bits

 

SSB Index 2:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 2

      advance: 1728 bits

 

SSB Index 3:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 3

      advance: 2592 bits

 

SSB Index 4:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 4

      advance: 3456 bits

 

SSB Index 5:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 5

      advance: 4320 bits

 

SSB Index 6:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 6

      advance: 5184 bits

 

SSB Index 7:

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

  PBCH Message (32 bits):

    Hex: 0x40040001

    Binary: 00000010001000000000000010000000

  Overhead Bits Breakdown:

    SFN 4 LSB (4 bits): 1110 (14)

    HRF (1 bit): 0

    k_SSB MSB (1 bit): 0

  Scrambling Parameters:

    Payload Scrambling (before CRC):

      c_init: 0x000001F4

      v (from SFN): 3

      advance: 87 bits

    PBCH Scrambling (after rate matching):

      c_init: 0x000001F4

      v (from SSB index): 7

      advance: 6048 bits

 

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

 

[DEBUG] create_ssb_masks: n_cell_id=500, v_bar=0

[DEBUG] create_ssb_masks: ssb_scs_ratio=1.0, dmrs_spacing=4, v_bar_scaled=0

[DEBUG] generate_pbch_dmrs_sequence:

  n_cell_id=500, ssb_index=0

  term1 = (0+1) * ((500//4)+1) = 126

  term2 = (0+1) = 1

  term3 = 500 % 4 = 0

  c_init = 2^11*126 + 2^6*1 + 0 = 258112

  Generated Gold sequence: length=288 bits

  Gold sequence statistics: sum=136, mean=0.472

  Generated DMRS sequence: length=144 QPSK symbols

  DMRS magnitude stats: min=1.000000, max=1.000000, mean=1.000000

  DMRS magnitude should be ~1.0 (normalized QPSK): mean=1.000000

 

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

SSB Resource Grid Visualization Complete!

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

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).

 

Parameters

The following parameters define the overall NR carrier context and where the SSB burst is placed inside that carrier. On the left, you select the SSB case and frequency range (which determines the allowed SSB patterns and rules), set the SSB and PDSCH subcarrier spacings, choose L<sub>max</sub> and the SSB TX bitmap to control how many SSBs can appear in a burst and which ones are enabled, and set the channel bandwidth and PCI (Cell ID) that drive the synchronization sequences. On the right, you specify the 3GPP SSB frequency positioning using the Point A reference, including offsetToPointA and kSSB, so the tool can place the 240-subcarrier SSB precisely within the channel grid (or auto-center it) in a way that matches the standard’s resource grid mapping.

Followings are brief descriptions on each parameters

  • SSB Case: Selects the 3GPP SSB “case” (A–E), which defines the allowed SSB time pattern and burst structure for a given deployment scenario.
  • Frequency Range: Chooses the operating frequency region (e.g., FR1 sub-range). This constrains which cases and positioning rules are valid.
  • SSB SCS (kHz): Sets the subcarrier spacing used inside the SSB (PSS/SSS/PBCH/PBCH-DMRS). This affects SSB bandwidth in Hz and symbol timing.
  • PDSCH SCS (kHz): Sets the subcarrier spacing for the main carrier/grid where SSB is placed. If different from SSB SCS, the tool must map between the two grids.
  • Lmax: Maximum number of possible SSBs in one burst (e.g., 4/8/64 depending on case/frequency). It defines the candidate SSB indices.
  • SSB TX Bitmap: Bitmask that enables/disables individual SSB indices within the burst (which SSBs are actually transmitted).
  • Channel BW (MHz): The overall carrier bandwidth. This impacts the total number of RBs, FFT size, and available frequency space for placing the SSB.
  • Cell ID (PCI): Physical Cell ID used to generate PSS/SSS sequences and affects PBCH DMRS (via v̄ = NcellID mod 4) and related scrambling parameters.
  • offsetToPointA (3GPP): RB offset from Point A to the SSB reference location (defined in 15 kHz RB units). It anchors the SSB frequency position relative to the carrier.
  • kSSB (3GPP): Subcarrier offset (in 15 kHz subcarrier units) for fine frequency placement of the SSB relative to the RB grid.
  • Subcarrier offset (Hz / RB units): A derived readout showing where the SSB lands inside the channel (useful for checking it is centered or within allowed ranges).

 

The MIB parameter configures the key MIB (Master Information Block) fields that the gNB broadcasts on PBCH inside the SSB. These parameters describe the cell’s basic frame timing (SFN), the common numerology used for initial access, the SSB’s frequency offset reference, and the control-channel bootstrap information (CORESET#0 and SearchSpace#0) that lets a UE find and decode the first downlink control. It also includes basic access restrictions and mobility hints (cell barred and intra-frequency reselection). The tool then packs these settings into the encoded MIB payload so you can see exactly what will be transmitted.

NOTE : This parameter in this script will be affecting the contents of PBCH and it does not influence the resource grid structure

Followings are brief descriptions on each parameters

  • System Frame Number (SFN): Sets the frame timing reference broadcast in the MIB, so the UE can align to the network’s radio frame count.
  • Subcarrier Spacing Common: Defines the “common” numerology used for initial access and SSB-related procedures (the baseline SCS the UE assumes first).
  • SSB Subcarrier Offset (kSSB LSB): Indicates the SSB subcarrier offset relative to Point A / common grid (LSB part used in MIB), helping the UE locate the SSB in frequency.
  • DMRS Type A Position: Selects the Type A DMRS symbol position used for control-region/PDSCH mapping rules that are signaled via MIB.
  • CORESET0 Index: Points to a predefined CORESET#0 configuration (time/frequency resources) used for the initial control channel that carries scheduling for SIB1.
  • SS0 Index: Points to a predefined SearchSpace#0 configuration, telling the UE where to monitor PDCCH for the initial messages (e.g., scheduling of SIB1).
  • Cell Barred: Broadcast access restriction flag. If enabled, the cell indicates it should not be selected for normal camping/initial access.
  • Intra-Freq Reselection Allowed: Mobility hint indicating whether the UE is allowed to reselect within the same frequency layer under the broadcast rules.
  • Encoded MIB Payload (24 bits): Shows the packed 24-bit MIB content produced from the fields above (often displayed in hex/binary/bytes) for verification and debugging.

 

The export parameters define how the tool generates the time-domain IQ output for the SSB burst and how it is saved to a file. You set the sample rate to control the waveform sampling resolution, and you choose the duration to decide how long the generated capture should be. The SSB period configures how often the SSB burst is repeated within that duration. You can optionally normalize the waveform amplitude to a fixed level for consistent scaling. Finally, you specify the output file name (and location) and export the generated binary IQ data.

Followings are brief descriptions on each parameters

  • Sample Rate (Ms/s): Sets the sampling frequency used to generate the time-domain IQ waveform. It must be consistent with the FFT size and subcarrier spacing so the OFDM waveform maps cleanly into samples.
  • Duration (ms): Total length of the exported IQ data in milliseconds. This determines how many samples are written to the output file.
  • SSB Period (ms): Controls the repetition interval of the SSB burst within the generated waveform. A shorter period repeats SSB more frequently; a longer period inserts more “gap” time between bursts.
  • Normalize (amplitude to 1.0): If enabled, scales the generated IQ waveform so the peak (or reference) amplitude is normalized. This helps keep amplitude consistent across different configurations.
  • File Name: Name (and typically path) of the exported binary IQ output file (e.g., ssb_output.bin).
  • Browse...: Opens a file dialog to choose the destination path/name for the export.
  • Export: Generates the IQ samples using the current settings and writes them to the selected output file.

 

Full Resource Grid

This view gives a high-level summary of how the SSB burst is placed inside the generated NR resource grid over time and frequency. It visualizes where the SSB-related signals (PSS, SSS, PBCH, and PBCH-DMRS) appear across OFDM symbols and subcarriers, so you can quickly confirm the SSB timing pattern, frequency location within the configured channel bandwidth, and overall span of the generated waveform before exporting IQ data.

Followings are the brief descriptions on each components of the plot

  • Horizontal axis (time): OFDM symbol index across the half-frame. Only specific symbol ranges contain energy, so this confirms that SSBs are transmitted in discrete symbol locations, not continuously.
  • SSB instances: Repeated blocks in time correspond to active SSB indices enabled by the SSB bitmap. The small numbers above each block indicate the SSB index within the SS burst set.
  • Vertical axis (frequency): Subcarrier index of the full carrier grid. Most of the grid is empty, so you can see that SSB occupies only a small part of the full carrier.
  • SSB bandwidth: The dashed horizontal lines mark the 240 consecutive subcarriers used by each SSB, so it clearly shows how narrow the SSB is relative to the 50 MHz channel.
  • Frequency positioning: The absolute vertical placement of the SSB region is determined by offsetToPointA and kSSB, which fix the SSB location with respect to Point A.
  • Internal SSB structure: Within each SSB block, different colors represent PSS, SSS, PBCH, and PBCH DMRS, arranged according to the fixed 4-symbol × 240-subcarrier SSB pattern.
  • PBCH DMRS pattern: The interleaved DMRS REs inside the PBCH region confirm that DMRS masking and mapping are applied correctly.
  • Empty REs: All non-SSB REs remain zero, so this highlights the implementation approach: create the full resource grid first, then map SSB content selectively via masks.
  • Overall validation: This figure validates time placement, frequency placement, and internal SSB structure for the configured Case B SSB transmission.

 

SSB Structure

This SSB Structure view illustrates the internal layout of a single Synchronization Signal Block (SSB) on the time–frequency grid, so you can verify that the four OFDM symbols are populated with the correct physical signals per 3GPP mapping. It shows where PSS and SSS are placed for cell search, and where PBCH and its DMRS are placed for broadcasting and enabling coherent PBCH demodulation, making it easy to confirm the expected 240-subcarrier SSB span and the symbol-by-symbol composition before generating or exporting the waveform.

Followings are the brief descriptions on each components of the plot

  • Vertical axis: Subcarrier index within the SSB. Only the SSB-local frequency range is shown, not the full carrier.
  • Horizontal axis: SSB symbol index from Symbol 0 to Symbol 3, corresponding to the four OFDM symbols that form a single SSB.
  • Symbol 0 (PSS): The Primary Synchronization Signal occupies 127 consecutive subcarriers, centered within the 240-subcarrier SSB bandwidth. Remaining subcarriers are unused.
  • Symbol 1 (PBCH): This symbol carries PBCH data with PBCH DMRS interleaved in frequency. DMRS appears on every fourth subcarrier, enabling channel estimation for PBCH.
  • Symbol 2 (SSS + PBCH): The Secondary Synchronization Signal occupies 127 subcarriers in the center. PBCH data continues on both sides of the SSS region, following the 3GPP-defined layout.
  • Symbol 3 (PBCH): PBCH transmission continues, again with PBCH DMRS interleaved across frequency in a fixed pattern.
  • Color coding: Distinct colors indicate PSS, SSS, PBCH, PBCH DMRS, and unused REs, making the internal SSB composition visually explicit.
  • DMRS pattern: PBCH DMRS is placed at fixed subcarrier offsets, repeating every fourth subcarrier, which matches the specification and validates correct mask generation.
  • Center alignment: Both PSS and SSS are centered within the SSB bandwidth, confirming correct frequency centering independent of the SSB’s absolute position in the carrier.
  • Specification compliance: The layout exactly matches 3GPP TS 38.211 Section 7.4.3, verifying that symbol usage and frequency allocation are implemented correctly.

 

SSB Time Pattern

This SSB Time Pattern view summarizes when each SSB is transmitted over time within a 5 ms half-frame, so you can quickly confirm the burst scheduling used for initial access and beam sweeping. It visualizes the slot-by-slot placement of SSBs based on the selected SSB case, subcarrier spacing, Lmax, and SSB TX bitmap, letting you verify the intended SSB periodicity and the exact time locations (slot/symbol windows) where SSBs appear versus where the grid remains empty.

Followings are the brief descriptions on each components of the plot

  • Upper panel (OFDM-symbol view): The horizontal axis shows the OFDM symbol index across the half-frame. Orange regions indicate symbols carrying SSBs, while dark regions indicate empty symbols.
    • SSB grouping: SSB symbols appear in clusters, reflecting the fact that each SSB occupies 4 consecutive OFDM symbols.
    • SSB indices: Numbers above the orange clusters correspond to the SSB index within the SS burst set, as defined by the Case B pattern.
    • Active symbols: For Case B, SSBs are transmitted at symbol indices {4, 8, 16, 20, 32, 36, 44, 48}, which matches the highlighted regions.
    • Empty symbols: Large gaps between clusters show that no SSB energy is transmitted during most OFDM symbols in the half-frame.
  • Lower panel (time-in-ms view): The horizontal axis is expressed in time (ms), making it easier to relate SSB transmission to frame timing.
    • Slot boundaries: Vertical dashed lines indicate slot boundaries. Each slot duration is approximately 0.5 ms for 30 kHz SCS.
    • SSB burst duration: The orange blocks at the beginning of the half-frame show that the SSB burst is confined to an early time window, followed by a long idle period.
    • Case B characteristic: The pattern reflects a medium SCS (30 kHz) deployment where SSBs are denser than Case A but still limited to a specific burst region.
    • Bitmap relationship: Which of these potential SSB locations are actually transmitted is controlled by the SSB bitmap, which enables or disables individual SSB indices.
    • Design implication: This visualization confirms that the implementation correctly separates time-pattern generation from frequency-domain grid mapping.

 

Constellation

This Constellation view gives a quick sanity check of the modulation mapping used inside the SSB by plotting the ideal I/Q points for each SSB component. By separating PSS/SSS and the PBCH-related signals (PBCH payload and PBCH DMRS), it helps you confirm that each part is using the expected modulation (e.g., BPSK vs QPSK) and that the generated symbols land on the correct constellation points for the selected Cell ID, SSB case, and grid configuration

Followings are the brief descriptions on each components of the plot

  • PSS constellation: The Primary Synchronization Signal uses BPSK modulation. The plot shows 127 symbols located at ±1 on the in-phase axis, with zero quadrature component, confirming correct BPSK mapping.
  • SSS constellation: The Secondary Synchronization Signal also uses BPSK modulation with 127 symbols. The constellation points mirror the PSS behavior but are generated from a different sequence definition.
  • PBCH constellation: The Broadcast Channel uses QPSK modulation. The plot shows 432 symbols evenly distributed over the four QPSK constellation points.
  • PBCH DMRS constellation: PBCH DMRS also uses QPSK. The plot contains 180 symbols, showing clean clustering at the four ideal QPSK points, which confirms correct reference-signal generation.
  • Combined SSB constellation: This plot overlays PSS, SSS, PBCH, and PBCH DMRS symbols together. BPSK points from PSS/SSS and QPSK points from PBCH/DMRS coexist without distortion, confirming correct multiplexing.
  • Symbol counts: The number of plotted symbols for each component matches the expected counts defined by 3GPP TS 38.211, validating correct RE allocation and masking.
  • Amplitude normalization: All constellations are centered and properly normalized, indicating that no unintended scaling or phase rotation has been applied.
  • Cell ID dependence: PSS, SSS, and PBCH DMRS symbol sequences are generated based on the configured cell ID, which affects the exact symbol ordering but not the constellation geometry.
  • Implementation check: This view acts as a final sanity check that sequence generation, modulation, and grid mapping are consistent before OFDM modulation or channel processing.

 

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 SSB Generation: Generates all SSB components (PSS, SSS, PBCH, PBCH DMRS) per 3GPP specifications.
  • Full PBCH Encoding Chain: Implements the complete PBCH encoding pipeline including MIB packing, CRC-24C, polar coding, rate matching, and scrambling.
  • Interactive GUI: Tkinter-based interface for configuring SSB parameters, MIB fields, and visualization.
  • Time-Domain IQ Export: Exports binary IQ files (.bin format) with metadata for use with detection/decoding tools.
  • Resource Grid Visualization: Multiple visualization tabs showing resource grid structure, time patterns, and constellation plots.

What is Implemented ?

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

Feature

Description

3GPP Reference

PSS Sequence Generation

BPSK sequence generation for n_id_2 (0, 1, 2)

TS 38.211 Section 7.4.2.2.1

SSS Sequence Generation

BPSK sequence generation for n_id_1 (0-335)

TS 38.211 Section 7.4.2.3.1

PBCH DMRS Sequence Generation

Gold sequence-based DMRS generation

TS 38.211 Section 7.4.1.4

MIB Payload Encoding

24-bit MIB information element packing

TS 38.331

PBCH Message Packing

32-bit message packing (MIB + SSB index + half-frame + kSSB MSB)

TS 38.212 Section 7.1.1

PBCH Payload Scrambling

Gold sequence-based payload scrambling

TS 38.211 Section 7.3.3

CRC-24C Computation

Byte-based table lookup CRC-24C (matches srsRAN)

TS 38.212 Section 5.1

Polar Interleaving

164-element interleaver pattern for K=56

TS 38.212 Table 5.3.1.1-1

Channel Allocation

Frozen set computation for polar code

TS 38.212

Polar Encoding

Systematic polar encoding (N=512)

TS 38.212

Sub-block Interleaving

864-element BLK_INTERLEAVER_9 pattern

TS 38.212 Section 5.4.1.1

Rate Matching

PBCH rate matching (puncturing to 864 bits)

TS 38.212 Section 7.1.4

PBCH Scrambling

Gold sequence-based bit-level scrambling

TS 38.211 Section 7.3.3

QPSK Modulation

Bit-to-symbol mapping for PBCH (432 symbols)

TS 38.211

SSB Resource Grid Construction

4 symbols × 240 subcarriers SSB structure

TS 38.211 Section 7.4.3

SSB Mask Generation

PSS/SSS/PBCH/DMRS mask creation

TS 38.211

SSB Positioning

SSB symbol position calculation (Case A-E)

TS 38.213 Section 4.1

OFDM Modulation

IFFT and cyclic prefix addition

-

Time-Domain IQ Generation

Complete time-domain signal generation

-

Binary IQ Export

Export to .bin format (4-byte float I/Q pairs)

-

Metadata Export

JSON metadata file generation

-

Resource Grid Visualization

Full resource grid heatmap

-

SSB Structure Visualization

SSB structure diagram

-

Time Pattern Visualization

SSB burst timing pattern

-

Constellation Visualization

QPSK constellation plots

-

Interactive GUI

Tkinter-based GUI with tabbed interface

-

Parameter Configuration

Tabbed parameter settings (SSB, MIB, Export)

-

What is NOT Implemented ?

Feature

Description

3GPP Reference

Multi-Antenna Transmission

MIMO transmission with multiple antenna ports

TS 38.211

Beamforming

Beamforming weights application

TS 38.211

Power Control

Dynamic power control for SSB

-

Multiple SSB Burst Patterns

Complex SSB burst pattern generation

TS 38.213

SIB1 Encoding

System Information Block 1 encoding

TS 38.212

PDCCH Encoding

PDCCH channel encoding

TS 38.212

PDSCH Encoding

PDSCH channel encoding

TS 38.212

Description of Parameters (Global Variables)

SSB Configuration Parameters

Parameter

Type

Default

Description

3GPP Reference

SSB_CASE

str

'B'

SSB case ('A', 'B', 'C', 'D', 'E'). Case A: 15 kHz SCS FR1, Case B: 30 kHz SCS FR1, Case C: 30 kHz SCS FR1 (paired), Case D: 120 kHz SCS FR2, Case E: 240 kHz SCS FR2

TS 38.213 Section 4.1

L_MAX

int

8

Maximum number of SS/PBCH blocks in a half frame (5ms). FR1 (< 3 GHz): 4, FR1 (3-6 GHz): 8, FR2 (> 6 GHz): 64

TS 38.213 Section 4.1

SSB_TX_BITMAP

str

'11111111'

SSB transmission bitmap (length up to L_MAX). '1' = transmit, '0' = skip. Example: '1111' for 4 SSBs, '11111111' for 8 SSBs

TS 38.213

SSB_CASE_PARAMS

dict

-

Dictionary containing SSB case parameters: SCS (kHz), first_symbols, slot_pattern_period, l_max, default_bitmap, default_bw_mhz, frequency_ranges

TS 38.213 Table 4.1-1

SSB_SCS_KHZ

float

Derived

SSB subcarrier spacing in kHz (derived from SSB_CASE)

TS 38.211

SSB_FIRST_SYMBOLS

list

Derived

First symbol positions for SSB case (derived from SSB_CASE)

TS 38.213

SSB_SUBCARRIER_SPACING

float

Derived

SSB subcarrier spacing in Hz (SSB_SCS_KHZ * 1e3)

TS 38.211

Channel Bandwidth Configuration

Parameter

Type

Default

Description

3GPP Reference

CHANNEL_BW_MHZ

int

20

Channel bandwidth in MHz (5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 100)

TS 38.101

PDSCH_SCS_KHZ

int

30

PDSCH subcarrier spacing in kHz (grid SCS: 15, 30, 60, 120, 240)

TS 38.101

MAX_RBS_TABLE

dict

-

Maximum RBs per channel bandwidth and SCS lookup table

TS 38.101

FFT_SIZE_TABLE

dict

-

FFT sizes for different bandwidths (5 MHz: 512, 10-30 MHz: 1024-2048, 40-100 MHz: 4096)

-

MAX_RBS

int

Derived

Maximum resource blocks for configured bandwidth and SCS (derived from MAX_RBS_TABLE)

TS 38.101

FFT_SIZE

int

Derived

FFT size for configured bandwidth (derived from FFT_SIZE_TABLE)

-

MAX_SUBCARRIERS

int

Derived

Maximum subcarriers (MAX_RBS * 12)

-

SSB Physical Parameters

Parameter

Type

Default

Description

3GPP Reference

SSB_NUM_RBS

int

20

SSB always occupies 20 RBs (240 subcarriers)

TS 38.211 Section 7.4.3

SSB_NUM_SUBCARRIERS

int

240

SSB subcarrier count (20 RBs * 12 subcarriers/RB)

TS 38.211 Section 7.4.3

SSB_NUM_SYMBOLS

int

4

SSB always occupies 4 OFDM symbols

TS 38.211 Section 7.4.3

PSS_SSS_NUM_SUBCARRIERS

int

127

PSS and SSS each occupy 127 subcarriers

TS 38.211 Section 7.4.2

PSS_SSS_START_SC

int

56

Starting subcarrier within SSB (centered, SC 56-182)

TS 38.211 Section 7.4.3

PSS_SSS_END_SC

int

183

Ending subcarrier within SSB (exclusive, so 56-182)

TS 38.211 Section 7.4.3

PBCH_LEFT_END_SC

int

48

Left PBCH ends at SC 47 (SC 0-47)

TS 38.211 Section 7.4.3

PBCH_RIGHT_START_SC

int

192

Right PBCH starts at SC 192 (SC 192-239)

TS 38.211 Section 7.4.3

PBCH_NUM_RES

int

432

PBCH occupies 432 REs per SSB

TS 38.211 Section 7.4.3

PBCH_DMRS_DENSITY

int

3

DMRS on every 4th subcarrier (v=0,1,2,3)

TS 38.211 Section 7.4.1.4.1

Time Domain Configuration

Parameter

Type

Default

Description

3GPP Reference

SLOT_DURATION_MS

float

Derived

Slot duration in ms (1.0 / (SSB_SCS_KHZ / 15))

TS 38.211

HALF_FRAME_MS

float

5.0

Half frame duration in milliseconds

TS 38.211

NUM_SLOTS_IN_HALF_FRAME

int

Derived

Number of slots in 5ms half frame

TS 38.211

NUM_SYMBOLS_PER_SLOT

int

14

Number of OFDM symbols per slot (normal CP)

TS 38.211

NUM_OFDM_SYMBOLS

int

Derived

Total OFDM symbols in half frame

TS 38.211

SSB Position Parameters

Parameter

Type

Default

Description

3GPP Reference

COMMON_SCS_KHZ

int

15

Common raster subcarrier spacing (15 kHz for FR1)

TS 38.211

OFFSET_TO_POINTA_RB

int

Derived

Offset to Point A in RB units at 15 kHz common raster

TS 38.211

K_SSB

int

Derived

Subcarrier offset (0-23) at 15 kHz common raster

TS 38.211

SSB_START_SC

int

Derived

SSB start subcarrier at SSB SCS (derived from offsetToPointA and k_SSB)

TS 38.211

SSB_OFFSET_RB

int

Derived

SSB offset in RB units at SSB SCS

TS 38.211

PBCH Encoding Constants

Parameter

Type

Default

Description

3GPP Reference

PBCH_NR_M

int

432

Number of QPSK symbols (432 REs for PBCH data)

TS 38.211 Section 7.3.3

PBCH_NR_E

int

864

Number of encoded bits after rate matching (432 symbols * 2 bits)

TS 38.212 Section 7.1.4

PBCH_NR_N

int

512

Polar code block size (N=512)

TS 38.212

PBCH_NR_A

int

32

Payload size (24 MIB bits + 8 overhead bits: SFN LSB, HRF, SSB index/k_SSB MSB)

TS 38.212 Section 7.1.1

PBCH_NR_K

int

56

Information block size (32 payload + 24 CRC)

TS 38.212

PBCH_G_PATTERN

list

-

PBCH message interleaving pattern G (32 elements, Table 7.1.1-1)

TS 38.212 Section 7.1.1

BLK_INTERLEAVER_9

list

-

Block interleaver pattern for n=9 (864 elements, sub-block interleaving)

TS 38.212 Section 5.4.1.1

MOTHER_CODE_9

list

-

Mother code pattern for n=9 (512 elements, polar code reliability ordering)

TS 38.212

POLAR_INTERLEAVER_PATTERN

list

-

Polar interleaver pattern (164 elements, Table 5.3.1.1-1)

TS 38.212 Table 5.3.1.1-1

POLAR_INTERLEAVER_K_MAX_IL

int

164

Maximum K for polar interleaver (164 for PBCH K=56)

TS 38.212

Cell Configuration

Parameter

Type

Default

Description

3GPP Reference

N_CELL_ID

int

500

Physical cell identity (PCI, 0-1007)

TS 38.211

Debug Configuration

Parameter

Type

Default

Description

DEBUG

bool

True

Enable/disable debug prints throughout the code

Description of Functions

MIB and PBCH Encoding Functions

encode_mib_payload(self)

Encodes MIB information elements into a 24-bit payload per 3GPP TS 38.331.

Returns:

  • tuple: (payload_bits_list, payload_hex_str, payload_bits_array)
    • payload_bits_list: List of 24 bits
    • payload_hex_str: Hex string representation
    • payload_bits_array: NumPy array of 24 bits

3GPP Reference: TS 38.331 Section 6.2.2

encode_pbch(mib_payload_bits, n_cell_id, sfn, ssb_idx, k_ssb_msb, Lmax, n_hf=0)

Implements the complete PBCH encoding chain per 3GPP TS 38.211 and TS 38.212, starting from the 24-bit MIB payload and producing 432 QPSK PBCH symbols.

Parameters:

  • mib_payload_bits (np.ndarray): 24-bit MIB payload
  • n_cell_id (int): Cell ID (0-1007)
  • sfn (int): System Frame Number (0-1023)
  • ssb_idx (int): SSB index (0-7)
  • k_ssb_msb (int): k_SSB MSB (0 or 1)
  • Lmax (int): Maximum SSB indices (4, 8, or 64)
  • n_hf (int): Half-frame indicator (0 or 1)

Returns:

  • np.ndarray: 432 QPSK symbols (complex)

Processing Steps:

  1. PBCH message packing (32 bits)
  2. Payload scrambling (Gold sequence)
  3. CRC-24C addition (24 bits)
  4. Polar interleaving (56 bits)
  5. Channel allocation (frozen set)
  6. Polar encoding (512 bits)
  7. Sub-block interleaving (512 bits)
  8. Rate matching (864 bits)
  9. PBCH scrambling (Gold sequence)
  10. QPSK modulation (432 symbols)

3GPP References:

  • TS 38.211 (PBCH generation and scrambling)
  • TS 38.212 (PBCH encoding and rate matching)

compute_crc24c(bits)

Computes the CRC-24C checksum using a byte-based table lookup method designed to match common reference implementations (e.g., srsRAN).

Parameters:

  • bits (np.ndarray): Input bits

Returns:

  • np.ndarray: 24-bit CRC

3GPP Reference: TS 38.212 Section 5.1

SSB Sequence Generation Functions

generate_pss_sequence(n_id_2)

Generates the PSS (Primary Synchronization Signal) sequence as a 127-length BPSK sequence derived from n_id_2.

Parameters:

  • n_id_2 (int): Physical layer cell identity group (0, 1, or 2)

Returns:

  • np.ndarray: PSS sequence (127 complex values, BPSK)

3GPP Reference: TS 38.211 Section 7.4.2.2.1

generate_sss_sequence(n_id_1, n_id_2)

Generates the SSS (Secondary Synchronization Signal) sequence as a 127-length BPSK sequence derived from n_id_1 and n_id_2.

Parameters:

  • n_id_1 (int): Physical layer cell identity (0-335)
  • n_id_2 (int): Physical layer cell identity group (0, 1, or 2)

Returns:

  • np.ndarray: SSS sequence (127 complex values, BPSK)

3GPP Reference: TS 38.211 Section 7.4.2.3.1

generate_pbch_dmrs_sequence(n_cell_id, ssb_idx, Lmax)

Generates the PBCH DMRS sequence using a Gold-sequence-based initialization and QPSK mapping for the given cell ID and SSB index.

Parameters:

  • n_cell_id (int): Cell ID (0-1007)
  • ssb_idx (int): SSB index (0-7)
  • Lmax (int): Maximum SSB indices (4, 8, or 64)

Returns:

  • np.ndarray: DMRS sequence (144 complex values, QPSK)

3GPP Reference: TS 38.211 Section 7.4.1.4

generate_gold_sequence(length, c_init)

Generates a Gold sequence of the requested length using the specified initialization value, typically used for scrambling and DMRS generation.

Parameters:

  • length (int): Sequence length
  • c_init (int): Initialization value

Returns:

  • np.ndarray: Gold sequence (bits)

Resource Grid Functions

create_ssb_masks(num_symbols, num_subcarriers, ssb_start_sc, ssb_symbol_positions, ssb_num_subcarriers=None, ssb_scs_ratio=1.0, n_cell_id=0)

Creates per-component masks for the SSB region (PSS, SSS, PBCH, PBCH DMRS) so the generator can place each signal on the correct RE locations within the overall resource grid.

Parameters:

  • num_symbols (int): Total OFDM symbols
  • num_subcarriers (int): Total subcarriers
  • ssb_start_sc (int): SSB start subcarrier index
  • ssb_symbol_positions (list): SSB symbol start positions
  • ssb_num_subcarriers (int, optional): SSB subcarrier count (default: 240)
  • ssb_scs_ratio (float): SSB SCS ratio
  • n_cell_id (int): Cell ID

Returns:

  • dict: Dictionary of masks (pss, sss, pbch, pbch_dmrs, ssb_combined)

Time-Domain Generation Functions

generate_ssb_time_domain(self, sample_rate_hz, num_symbols, fft_size, cp_length, max_subcarriers, ssb_case, l_max, ssb_tx_bitmap, ssb_scs_khz, pdsch_scs_khz, n_cell_id, ssb_period_ms)

Generates time-domain IQ samples by mapping SSB components into the resource grid at the configured time/frequency locations, then applying OFDM modulation (IFFT + CP) to produce a continuous complex baseband waveform.

Parameters:

  • sample_rate_hz (float): Sample rate in Hz
  • num_symbols (int): Number of OFDM symbols
  • fft_size (int): FFT size
  • cp_length (int): Cyclic prefix length
  • max_subcarriers (int): Maximum subcarriers
  • ssb_case (str): SSB case ('A', 'B', 'C', 'D', 'E')
  • l_max (int): Maximum SSB indices
  • ssb_tx_bitmap (str): SSB transmission bitmap
  • ssb_scs_khz (float): SSB subcarrier spacing in kHz
  • pdsch_scs_khz (float): PDSCH subcarrier spacing in kHz
  • n_cell_id (int): Cell ID
  • ssb_period_ms (float): SSB period in milliseconds

Returns:

  • np.ndarray: Time-domain IQ samples (complex)