What is cell search — finding a cell in the dark TS 38.213 §4.1
Cell search is the procedure by which a UE acquires time and frequency synchronization with a cell and detects its physical-layer Cell ID. The UE has no prior knowledge of when or where the cell transmits — it only knows the raster of possible frequencies. It listens for two signals defined in TS 38.211: the primary synchronization signal (PSS) and the secondary synchronization signal (SSS), which together with the PBCH and its DM-RS form an SS/PBCH block — the lighthouse beacon every 5G cell broadcasts.
Consecutive symbols, one block
PBCH, PSS and SSS sit in consecutive OFDM symbols and form a single SS/PBCH block. The UE assumes SSS, PBCH DM-RS and PBCH data share the same EPRE; the PSS-to-SSS EPRE ratio is either 0 dB or 3 dB. That fixed power relationship is what lets the receiver combine the signals coherently.
Three unknowns to solve
Time: where does the symbol/frame boundary fall? Frequency: what's the carrier offset (CFO)? Identity: which of 1008 PCIs is this? PSS solves coarse timing + NID(2); SSS solves NID(1); PBCH+DM-RS deliver the MIB and the SSB index for fine frame timing.
EPRE & the −8/+8 dB window
If the UE has no dedicated higher-layer params, it may assume the PDCCH DMRS-to-SSS EPRE is within −8 dB and 8 dB when monitoring PDCCH for DCI 1_0 (SI/P/RA-RNTI), DCI 2_7 or 4_0 — the bound that makes blind initial-access decoding possible before the cell is fully configured.
1008 Cell IDs — NIDcell = 3·NID(1) + NID(2) §7.4.2.1
There are exactly 1008 unique physical-layer cell identities, split into 336 groups (NID(1) ∈ {0…335}) of 3 sectors each (NID(2) ∈ {0,1,2}). The group comes from the SSS; the sector from the PSS. That 336×3 factoring is the whole reason there are two sync signals — PSS narrows you to 3 candidates, SSS picks the group. Slide the knobs and build any PCI.
PSS — one m-sequence, three cyclic shifts §7.4.2.2.1
The PSS is a length-127 BPSK sequence dPSS(n) = 1 − 2x(m), where m = (n + 43·NID(2)) mod 127. The base sequence x is a single maximum-length sequence (m-sequence) from the LFSR x(i+7) = (x(i+4) + x(i)) mod 2 seeded with [1110110]. The three sectors are just three cyclic shifts of the same sequence — by 0, 43, and 86. Step the register, then watch the three shifts separate.
Why shift by 43?
127 / 3 ≈ 42.3, so shifts of 0, 43, 86 spread the three sectors as far apart on the 127-length ring as integers allow. The cross-correlation between any two shifted m-sequences is a flat −1/127 — near-orthogonal. So even at low SNR the correct sector wins by a clean margin, and the shift that maximises correlation directly reveals NID(2).
Timing falls out for free
Because the UE slides the local PSS replica across the incoming samples, the sample offset of the correlation peak is the cell's symbol timing. One PSS correlation therefore delivers both coarse time sync and the sector — and roughly localises the SSB in the 5 ms half-frame. The remaining ambiguity (which SSB in the burst) is resolved later by DM-RS + PBCH.
SSS — two m-sequences multiply into 336 codes §7.4.2.3.1
Where PSS had 3 hypotheses, the SSS must distinguish 336 groups. It does it by multiplying two length-127 m-sequences, each cyclically shifted by an amount derived from NID(1) and NID(2): a coarse shift m0 (15 steps × the NID(1)/112 block, plus 5·NID(2)) and a fine shift m1 (NID(1) mod 112). 15×112 ≈ enough product combinations to label all 336 groups uniquely.
[x(6)…x(0)] = [0 0 0 0 0 0 1] but use different feedback taps — x0: x(i+7)=x(i+4)+x(i); x1: x(i+7)=x(i+1)+x(i). Two different m-sequences, each shiftable 127 ways; their product spreads 336 groups across a code space with low pairwise correlation — so SSS detection is robust even after PSS has already used part of the SNR budget.The SS/PBCH block — 4 symbols × 240 subcarriers §7.4.3.1 + Table 7.4.3.1-1
An SS/PBCH block is 4 OFDM symbols (l = 0…3) by 240 contiguous subcarriers (k = 0…239). PSS lives in symbol 0 (subcarriers 56–182); SSS in symbol 2 (same 56–182); PBCH fills symbols 1 and 3 entirely and the edges of symbol 2; and the PBCH DM-RS threads through on a comb shifted by v = NIDcell mod 4. Change the PCI and watch the DM-RS comb slide — that shift is how neighbouring cells keep their pilots from colliding.
Table 7.4.3.1-1 — the map
| Channel | Symbol l | Subcarriers k |
|---|---|---|
| PSS | 0 | 56…182 |
| SSS | 2 | 56…182 |
| Set to 0 | 0 | 0…55, 183…239 |
| Set to 0 | 2 | 48…55, 183…191 |
| PBCH | 1, 3 | 0…239 |
| PBCH | 2 | 0…47, 192…239 |
| DM-RS | 1, 3 | 0+v, 4+v, 8+v, … 236+v |
| DM-RS | 2 | 0+v…44+v, 192+v…236+v |
The fixed facts
Every SS/PBCH block uses antenna port p = 4000 for PSS, SSS, PBCH and its DM-RS, and the same CP length and SCS across all four symbols.
PSS and SSS occupy only 127 of the 240 subcarriers (56–182); the guard subcarriers around them are set to zero to protect the correlation from adjacent-channel leakage.
DM-RS is 1 in every 4 subcarriers (3 RE per RB), shifted by v — so up to 4 cells can interleave their pilots on orthogonal combs.
Where in frequency does the SSB sit? — kSSB, NCRBSSB & CORESET#0 §7.4.3.1
Cases A–G fix the SSB in time; this fixes it in frequency. The SSB doesn't sit on the channel raster — it floats on a finer synchronization raster, so the UE must learn exactly which subcarriers it occupies. The anchor is kSSB: the subcarrier offset from subcarrier 0 of common resource block NCRBSSB up to the lowest subcarrier of the SS/PBCH block. Its 4 least-significant bits come from ssb-SubcarrierOffset; the most-significant bit rides in the PBCH payload (āĀ+5). From kSSB alone the UE learns whether CORESET#0 is even present.
offsetToPointA · 240 subcarriers = 20 RB wideThe CORESET#0 switch
From the MIB, a CORESET for the Type0-PDCCH common search space is present if kSSB < 24 (FR1) or < 12 (FR2). If kSSB > 23 (FR1) or > 11 (FR2), there's no CORESET#0 in this SSB — the UE finds the CORESET via PDCCH-ConfigCommon instead. That single threshold decides whether this SSB is a full "cell-defining" anchor or just a measurement beacon.
SSB types A vs B
Type A (µ∈{0,1}): kSSB ∈ {0…23} expressed in 15 kHz, NCRBSSB in 15 kHz. Type B (FR2-1/NTN µ∈{3,4}, FR2-2 µ∈{3,5,6}): kSSB ∈ {0…11} in the SSB/common SCS, but NCRBSSB always expressed in 60 kHz. The centre of subcarrier 0 of NCRBSSB coincides with subcarrier 0 of a CRB at subCarrierSpacingCommon.
The 3 MHz puncture
On a 3 MHz carrier there isn't room for all 20 SSB RBs. The UE is not expected to receive subcarriers 0–47 and 192–239 in any of the 4 symbols — the remaining 12 RB form the SS/PBCH block after puncturing. The PSS/SSS (subcarriers 56–182) survive untouched; only the PBCH edges are clipped.
ssb-SubcarrierOffset are available the moment the UE reads the first PBCH bits, but the MSB (āĀ+5) needs the full payload — and in shared spectrum that MSB doubles as the SSB-index bit. The k̄SSB ≥ 24 test disambiguates the two uses: large values are a true subcarrier offset; small ones get halved (2⌊k̄SSB/2⌋) because the spare bit was spent on the index. If ssb-SubcarrierOffset isn't signalled at all, kSSB is inferred from the raw frequency difference between the SSB and Point A.PBCH DM-RS — the pilot that smuggles the beam index §7.4.1.4.1
The PBCH DM-RS isn't just a channel-estimation pilot — its scrambling seed encodes the SS/PBCH block index. The sequence is QPSK: r(m) = (1−2c(2m))/√2 + j(1−2c(2m+1))/√2, and the Gold generator is initialised per block with cinit that mixes the cell ID with īSSB — the low bits of the candidate SSB index. Decode the DM-RS sequence and you've recovered which beam you're hearing, before decoding a single PBCH bit.
Power allocation inside the block — β scaling & EPRE ratios §7.4.3.1.1–.3 + §4.1
Every symbol in the block is scaled by a power factor before mapping: PSS by βPSS, SSS by βSSS, PBCH by βPBCH, and PBCH DM-RS by βPBCHDM-RS. These aren't arbitrary — they enforce the EPRE relationships the receiver relies on: SSS, PBCH-DM-RS and PBCH-data share one EPRE, while PSS is either equal (0 dB) or 3 dB hotter. Boost the PSS and watch the per-symbol power redistribute.
The one shared EPRE
The UE assumes SSS, PBCH DM-RS and PBCH data have the same EPRE. That equality is what lets the channel estimate from DM-RS be applied directly to PBCH data and to the SSS metric without any per-signal gain correction. PSS is treated separately — its 0/3 dB offset is known a-priori, so the correlator scales it out.
Why PSS may be 3 dB hot
PSS is detected first, at the lowest SNR, with no prior timing — the hardest job in the whole procedure. Allowing a 3 dB boost gives the initial correlation extra margin without touching the SSS/PBCH budget. Once timing is locked, the easier SSS and PBCH steps run at the nominal EPRE. The −8…+8 dB PDCCH-DMRS:SSS bound then lets the UE size Type0-PDCCH gain before any dedicated config exists.
Where do the SSBs land? — Cases A–G live designer TS 38.213 §4.1
A cell doesn't send one SSB — it sweeps a burst of up to Lmax beams through a 5 ms half-frame, each on a candidate set of OFDM-symbol positions fixed by the SCS. The first symbols of the candidate blocks follow a per-case pattern: {offsets} + step·n, with n ranging over a set that depends on carrier frequency. Pick a case and a band — the half-frame fills with the exact beam positions the standard mandates.
The pattern is SCS-locked
Cases A/C/F/G step by 14·2µ (one slot), Cases B/D by 28·2µ (two slots), Case E by 56. The offsets ({2,8}, {4,8,16,20}, …) place SSBs inside the slots while leaving symbols 0–1 and the slot edges free for CORESET#0 / control. Index 0 = the first symbol of the first slot in the half-frame.
Higher band → more beams
Below 3 GHz, a couple of wide beams suffice → Lmax = 4. FR1 above 3 GHz → 8. In FR2 (mmWave), narrow beams must paint the whole cell → Lmax = 64. The candidate-n set grows to pack that many SSBs into the same 5 ms.
SCS picked automatically
If ssbSubcarrierSpacing isn't signalled, the case is chosen from the frequency band (TS 38.101). A 30 kHz SSB can be Case B or C depending on the band table — the UE picks the case its band mandates, then knows exactly where to look.
Lmax & decoding the SSB index — DM-RS bits + PBCH bits TS 38.213 §4.1
Knowing which of the up-to-64 beams you've found is essential for frame timing and beam selection. The SSB index is assembled from two sources: the low bits from the DM-RS sequence (Chapter 7) and the high bits from the PBCH payload. How many of each depends on Lmax. Pick Lmax and watch the index ribbon assemble.
The decode rule
| Lmax | LSBs (DM-RS) | MSBs (PBCH payload) |
|---|---|---|
| 4 | 2 (+ nhf in īSSB) | — |
| 8 | 3 | — |
| 10 | 3 | 1 — āĀ+7 |
| 20 | 3 | 2 — āĀ+6, āĀ+7 |
| 64 | 3 | 3 — āĀ+5, āĀ+6, āĀ+7 |
Lmax = 8/10/20 appear with shared-spectrum access; 10 and 20 only there. 64 is the FR2 norm.
Why it matters for timing
The SSB index tells the UE which candidate position in the burst it locked onto — and therefore exactly where the frame boundary is, since the burst is anchored to the half-frame start.
It also names the beam. The UE measures several SSBs, picks the strongest index, and later reports it (e.g. in RACH via the SSB→RO mapping) so the gNB transmits toward it. Get the index wrong and you RACH on the wrong beam — into a null.
L̄max vs Lmax, and the QCL count NSSBQCL TS 38.213 §4.1 + Tables 4.1-1/4.1-2
In unlicensed spectrum, two SSB index counts diverge. L̄max is the number of candidate positions (4…64, set by the case); Lmax is the number of distinct transmitted SSB indexes. With shared-spectrum FR1, Lmax = 8 even when L̄max = 10 (15 kHz) or 20 (30 kHz) — because several candidates that share a beam are quasi-co-located (QCL). The QCL count NSSBQCL tells the UE how many candidates collapse onto one beam, via (NDM-RSPBCH mod NSSBQCL).
Tables 4.1-1 & 4.1-2 — NSSBQCL
| Region | scsCommon | LSB ssb-SCoffset | NSSBQCL |
|---|---|---|---|
| FR1 (4.1-1) | scs15or60 | 0 | 1 |
| scs15or60 | 1 | 2 | |
| scs30or120 | 0 | 4 | |
| scs30or120 | 1 | 8 | |
| FR2-2 (4.1-2) | scs15or60 | — | 32 |
| scs30or120 | — | 64 |
NSSBQCL can also be given directly by ssb-PositionQCL; otherwise it's read from the MIB via these tables.
What QCL actually buys the UE
Two SSBs are quasi-co-located 'typeA' + 'typeD' when (NDM-RSPBCH mod NSSBQCL) matches (FR1) — or (ī mod NSSBQCL) in FR2-2. Same statistics, same RX beam.
So the UE can combine measurements across QCL'd candidates and reuse one RX beam — critical in NR-U where LBT may drop any individual SSB. Within a discovery-burst window, a given index appears at most once, and the number of transmitted SSBs never exceeds NSSBQCL.
Half-frame periodicity & the SS burst set TS 38.213 §4.1
The burst repeats. ssb-periodicityServingCell sets how often the half-frame carrying SSBs comes round — 5, 10, 20, 40, 80 or 160 ms. For initial cell selection, a UE may assume SSBs occur with a periodicity of 2 frames (20 ms) — a safe default to search against before reading any config. And ssb-PositionsInBurst is a bitmap saying which of the Lmax candidate positions actually carry a beam — so the cell can transmit fewer beams than the maximum.
discoveryBurstWindowLength starting at the first symbol of the half-frame. ssb-PositionsInBurst then says which candidate indexes may be sent — but LBT can still drop some. The UE assumes a transmitted SSB and its candidate index match, and that within one window a given index appears at most once. That's why the same SSB block index, same centre frequency, is assumed quasi-co-located across windows.Transmission timing adjustment — NTA & the TA command TS 38.213 §4.2
Once synchronized in the downlink, the UE must align its uplink so every UE's signal arrives at the gNB on the same symbol boundary regardless of distance. That's timing advance. The first command rides in the Random Access Response as an absolute value TA ∈ {0…3846}; later commands are relative steps TA ∈ {0…63} centred on 31. The adjustment granularity is 16·64·Tc/2µ — finer at higher SCS. Slide TA and watch the UE's clock and range update.
NTA,offset — the fixed offset
On top of NTA, the UE applies a timing-advance offset NTA,offset from n-TimingAdvanceOffset (band-specific — it absorbs the DL/UL switching guard for TDD). With two CORESETs at coresetPoolIndex 0 and 1, a second NTA,offset (n-TimingAdvanceOffset2) applies to the second spatial filter / TCI state — so two TRPs can run two TAGs. If none is signalled, the UE takes the default from TS 38.133.
When the new timing applies
A TA command in slot n takes effect from the start of uplink slot n + k + 1 + 2µ·Koffset, wherek = ⌈Nslotsubframe,µ·(NT,1+NT,2+NTA,max+0.5)/Tsf⌉·2µ. NT,1 is the PDSCH processing time, NT,2 the PUSCH prep time (both capability 1), NTA,max the largest advance a 12-bit field can request, Tsf=1 ms. It gives the UE enough lead time to retune before transmitting.
Koffset & multi-BWP
Koffset = Kcell,offset − KUE,offset (from cellSpecificKoffset and a Differential Koffset MAC CE) pushes the apply-time further out for long round-trips — essential in NTN. With multiple active UL BWPs, the command is relative to the largest SCS; for a lower-SCS BWP the NTA,new is rounded to that BWP's granularity while still meeting the accuracy bound.
posUE-TA-AutoAdjustment / autonomousTA-AdjustmentEnabled, it may auto-update NTA at cell reselection while transmitting SRS for positioning.NTN timing pre-compensation — the Delaycommon(t) quadratic TS 38.213 §4.2
Over a satellite the round-trip is milliseconds and always changing as the bird races across the sky — far too much for the closed loop alone. So the UE pre-compensates the two-way delay on the service link (or the gNB↔UE link for ATG) using broadcast ephemeris, building a time-varying common delay: a constant, a linear drift, and a parabolic term that together track the satellite's geometry between epoch updates. Slide the three coefficients and watch the predicted delay curve bend.
ta-Common, ta-CommonDrift, ta-CommonDriftVariant, epochTime · Delaycommon = distance(t)/cWhy a quadratic?
Between epoch updates the satellite's slant range changes non-linearly — fastest at horizon, slowest at zenith. A constant would drift out of spec in milliseconds; a line is better but still curves away. The second-order term tracks the curvature so the UE's open-loop prediction stays valid for the whole validity window, and the closed-loop TA command only has to trim the small residual.
Service link + common, two halves
The total is split: a UE-specific part (computed by the UE from its GNSS position and the satellite ephemeris, NTA,adjUE) plus this common part (the feeder link / reference-point delay the whole cell shares). Delaycommon(t) is exactly distance(t)/c between the satellite and the uplink time-sync reference point — pure geometry, halved because TA is two-way.
Prove you own cell search — 16 questions
Straight from the clauses you just animated, including the advanced chapters. 13+ correct = spec-grade.