Module 3 — PBCH & MIB

PBCH Decoding —
From raw symbols to MIB bits

With PCI = 442 and symbol timing t = 4523 from PSS/SSS, the UE can now decode the Physical Broadcast Channel. PBCH carries the MIB — the first structured information from the network. This section walks through every step: DMRS generation, channel estimation, equalization, Polar decoding, and CRC.

TS 38.212 §7.1 TS 38.211 §7.3.3 TS 38.211 §7.4.1.4

Where PBCH lives in the SSB

PBCH occupies symbols 1, 2, and 3 of the SSB. In symbol 2, it shares space with SSS — PBCH uses the 48 subcarriers on each side of the SSS center block. Across all three symbols, PBCH has a total of 432 data subcarriers after removing DMRS positions.

PBCH subcarrier mapping — symbols 1, 2, 3 of SSB TS 38.211 §7.3.3.2
■ PBCH data ■ DMRS (every 4th SC, offset v = PCI mod 4 = 2) ■ SSS (center 127 of symbol 2)

Step 1 — Extract PBCH symbols

Using timing t = 4523 from PSS, the UE computes each PBCH symbol start, removes the cyclic prefix (144 samples), and runs a 2048-point FFT to get frequency-domain subcarriers.

PBCH symbol positions — PCI=442, t_PSS=4523TS 38.211 §7.3.3
// Symbol timing (symbol length = 2192 samples at 61.44 Msps)
Symbol 1: t = 4523 + 2192     = 6715  → skip CP (144) → FFT samples [6859..8906]
Symbol 2: t = 4523 + 2×2192   = 8907  → skip CP → FFT samples [9051..11098]
Symbol 3: t = 4523 + 3×2192   = 11099 → skip CP → FFT samples [11243..13290]

// Extract 240 center subcarriers from each 2048-bin FFT output
// → 240 complex values per symbol = PBCH + DMRS + (SSS in sym 2)

Step 2 — DMRS generation and channel estimation

PBCH DMRS is inserted every 4th subcarrier with offset v = PCI mod 4 = 2. The UE generates the expected DMRS sequence using the formula below, then uses it to estimate the channel at each DMRS position.

The PBCH DMRS sequence r(n) = (1/√2)(1−2c(2n)) + j(1/√2)(1−2c(2n+1)) where the pseudo-random sequence c(i) is initialised with

c_init = 2^11·(i_SSB+1)·(⌊N_ID^cell/4⌋+1) + 2^6·(i_SSB+1) + N_ID^cell mod 4
3GPP TS 38.211, Section 7.4.1.4.1
DMRS seed and channel estimation — PCI=442, SSB index=3TS 38.211 §7.4.1.4.1
// DMRS position offset
v = 442 mod 4 = 2  → DMRS at SC: 2, 6, 10, 14, 18, ...  (60 per symbol)

// DMRS seed
c_init = 2^11×(3+1)×(⌊442/4⌋+1) + 2^6×(3+1) + (442 mod 4)
      = 2048×4×111 + 256 + 2 = 908546

// Channel estimation (at each of 60 DMRS subcarriers):
H[k] = received[k] / DMRS_known[k]

// Example at k=2:
received[2]   = 0.450+0.380j
DMRS_known[2] = 0.707+0.707j
H[2] = 0.586∠−10°  (amplitude 0.586, phase shift −10°)

// Interpolate H[k] linearly between DMRS positions
// to estimate channel at all 180 data subcarriers
H[3]  ≈ (H[2]+H[6])/4×1 = 0.5873∠−10.25°
H[4]  ≈ (H[2]+H[6])/4×2 = 0.5885∠−10.50°
H[5]  ≈ (H[2]+H[6])/4×3 = 0.5898∠−10.75°

Step 3 — Equalization and QPSK demodulation

One-tap equalization and QPSK demodulation
// Remove channel distortion at each data subcarrier:
data_eq[k] = received[k] / H[k]

// Example at k=4:
received[4] = 0.412-0.089j,  H[4] = 0.5885∠−10.50°
data_eq[4]  = 0.707+0.000j  → QPSK symbol: +1+0j → bits 10

// QPSK: 2 bits per RE
Total data REs:  180 (sym1) + ~53 (sym2 sides) + 180 (sym3) = 413 REs
Total soft bits: 413 × 2 = 826 bits  (+ rate matching padding = 864)

Step 4 — Descrambling

The 864 bits are descrambled by XOR-ing with a pseudorandom sequence seeded by PCI = 442. This reverses the scrambling applied at the gNB.

Step 5 — Rate dematching → Polar decoding

5G NR uses Polar codes for PBCH. Polar codes are theoretically proven to achieve channel capacity. The decoder uses a Successive Cancellation List (SCL) decoder with list size L=8 — it maintains 8 candidate decoding paths simultaneously, selecting the one that passes the CRC.

The PBCH payload including the 24-bit CRC attachment shall be encoded using the Polar code. The encoded bits shall be rate-matched to the number of channel symbols assigned for PBCH transmission.
3GPP TS 38.212, Section 7.1.4

Step 6 — CRC check and payload extraction

PBCH payload — 32 bits decodedTS 38.212 §7.1.1
// Decoded 32-bit payload structure:
Bits [0..5]   = SFN MSBs (6 bits)           → 100011
Bit  [6]      = subCarrierSpacingCommon      → 1  (30 kHz)
Bits [7..10]  = ssb-SubcarrierOffset (k_SSB) → 0010 = 2
Bit  [11]     = dmrs-TypeA-Position          → 0  (symbol 2)
Bits [12..15] = controlResourceSetZero       → 0011 = 3
Bits [16..19] = searchSpaceZero              → 0010 = 2
Bit  [20]     = cellBarred                   → 0  (notBarred)
Bit  [21]     = intraFreqReselection         → 0  (allowed)
Bits [22..23] = spare                        → 00
Bits [24..31] = overhead (SFN LSBs, SSB idx)

// SFN reconstruction:
MSBs from MIB [0..5]: 100011
LSBs from overhead:         0101
Full SFN = 1000110101(bin) = 565
PBCH complete — UE now has:
SFN           → 565
SSB index     → 3
MIB (24 bits) → ready to parse field by field
Next          → Parse MIB → derive CORESET#0 position