OFDMと5G NRヌメロロジーのチートシート
TS 38.211に基づくNRのヌメロロジー、スロット長とサイクリックプレフィックス長、TS 38.101に基づくチャネル帯域幅ごとのリソースブロック数、比較用のLTE、OFDMの諸元を計算するコード。
このシートは、NRやLTEのキャリアを設定・シミュレーション・復号するエンジニアが、時間・周波数グリッドをひと目で確認するためのものです。ここに載せたNRの数値はすべて、3GPP TS 38.211(NRの物理チャネルと変調)、TS 38.101-1・TS 38.101-2(NR UEの無線送受信、FR1・FR2)、TS 38.104(NR基地局の無線送受信)のRelease 19版と照合しました。直交周波数分割多重(OFDM)の仕組みについては、ゼロから学ぶOFDMのレッスンから始めてください。
OFDMの関係式
| 量 | 式 | 例 |
|---|---|---|
| サブキャリア間隔 | Δf = fs / N_FFT | 30.72 Msample/s / 1024 = 30 kHz |
| 有効シンボル長 | T_u = 1 / Δf | 30 kHzで33.33 µs |
| サイクリックプレフィックス(CP) | チャネルの遅延広がりより長くする必要がある | 30 kHzのノーマルCPで2.34 µs |
| CPオーバーヘッド | T_cp / (T_u + T_cp) | NRのノーマルCPで約6.6% |
| 占有帯域幅 | N_RB × 12 × Δf | 273 × 12 × 30 kHz = 98.28 MHz |
| サンプルレート | N_FFT × Δf | 4096 × 30 kHz = 122.88 Msample/s |
リソースブロックは、周波数方向に連続する12本のサブキャリアです(TS 38.211)。サイクリックプレフィックスはチャネルの線形畳み込みを巡回畳み込みに変えるため、各サブキャリアには1つの複素利得だけがかかります。これが1タップの等化で済む理由です。
NRのヌメロロジー
TS 38.211は基本時間単位Tc = 1 / (480 kHz × 4096)とκ = 64を定義しています。フレームは10 ms、サブフレームは1 msです。ヌメロロジーインデックスμによりΔf = 15 × 2^μ kHzが決まります。
| μ | Δf | CPの種類 | サブフレームあたりのスロット数 | フレームあたりのスロット数 | スロット長 | 有効シンボル長 | ノーマルCP | 長いCP(1 msに2回) |
|---|---|---|---|---|---|---|---|---|
| 0 | 15 kHz | ノーマル | 1 | 10 | 1 ms | 66.67 µs | 4.688 µs | 5.208 µs |
| 1 | 30 kHz | ノーマル | 2 | 20 | 0.5 ms | 33.33 µs | 2.344 µs | 2.865 µs |
| 2 | 60 kHz | ノーマル、拡張 | 4 | 40 | 0.25 ms | 16.67 µs | 1.172 µs | 1.693 µs |
| 3 | 120 kHz | ノーマル | 8 | 80 | 125 µs | 8.33 µs | 0.586 µs | 1.107 µs |
| 4 | 240 kHz | ノーマル | 16 | 160 | 62.5 µs | 4.17 µs | 0.293 µs | 0.814 µs |
| 5 | 480 kHz | ノーマル | 32 | 320 | 31.25 µs | 2.08 µs | 0.146 µs | 0.667 µs |
| 6 | 960 kHz | ノーマル | 64 | 640 | 15.625 µs | 1.04 µs | 0.073 µs | 0.594 µs |
1スロットは、ノーマルCPでは14個のOFDMシンボル、拡張CP(60 kHzのみ、拡張CPは4.167 µs)では12個のシンボルです。ノーマルCPは144κ·2^−μ Tcです。0.5 msのハーフサブフレームごとに先頭シンボルには16κ Tcが加わるため、どのμでもスロットが1 msのサブフレームの境界にそろいます。表のスロット長以降の列は、TS 38.211の式から後述のコードで計算した値です。
どこでどのヌメロロジーを使うか
| 用途 | サブキャリア間隔 |
|---|---|
| FR1、データ(TS 38.101-1) | 15、30、60 kHz |
| FR2、データ(TS 38.101-2) | 60 kHz・120 kHz、およびオプション扱いの480 kHz・960 kHz |
| SS/PBCHブロック(TS 38.213のケースA〜G) | 15 kHz(A)、30 kHz(B、C)、120 kHz(D)、240 kHz(E)、480 kHz(F)、960 kHz(G) |
TS 38.104では、FR1を410 MHz〜7125 MHz、FR2-1を24250 MHz〜52600 MHz、FR2-2を52600 MHz〜71000 MHzと定義しています。SS/PBCHブロックは、時間方向に4個のOFDMシンボル、周波数方向に240本のサブキャリア(20リソースブロック)を占めます。
チャネル帯域幅ごとのリソースブロック数
TS 38.101-1 Table 5.3.2-1(FR1)による最大送信帯域幅構成N_RBです。N/Aはその組み合わせが定義されていないことを示します。
| チャネル帯域幅 | 15 kHz | 30 kHz | 60 kHz |
|---|---|---|---|
| 5 MHz | 25 | 11 | N/A |
| 10 MHz | 52 | 24 | 11 |
| 15 MHz | 79 | 38 | 18 |
| 20 MHz | 106 | 51 | 24 |
| 25 MHz | 133 | 65 | 31 |
| 30 MHz | 160 | 78 | 38 |
| 40 MHz | 216 | 106 | 51 |
| 50 MHz | 270 | 133 | 65 |
| 60 MHz | N/A | 162 | 79 |
| 80 MHz | N/A | 217 | 107 |
| 100 MHz | N/A | 273 | 135 |
元の表には3、7、35、45、70、90 MHzの行もあります。FR2(TS 38.101-2 Table 5.3.2-1)は次のとおりです。
| チャネル帯域幅 | 60 kHz | 120 kHz |
|---|---|---|
| 50 MHz | 66 | 32 |
| 100 MHz | 132 | 66 |
| 200 MHz | 264 | 132 |
| 400 MHz | N/A | 264 |
帯域幅パート(bandwidth part)は、これらのリソースブロックの一部で、独自のヌメロロジーを持ちます。UEはキャリアより狭い帯域幅パートを使うことがあります。
LTEとの比較
TS 36.211(E-UTRAの物理チャネルと変調)では、Ts = 1 / (15000 × 2048) s、307200 Tsからなる10 msのフレーム、0.5 msのスロット2つからなる1 msのサブフレームを使います。LTEのノーマルCPは、スロットの先頭シンボルで160 Ts、残り6シンボルで144 Tsです。拡張CPは512 Tsです。144 Tsは144κ Tcに等しいため、15 kHzではNRのμ = 0と同じ時間長になります。LTEは特殊な用途向けに7.5 kHz、3.75 kHz、1.25 kHzの間隔も定義しています。
コード: TS 38.211の式による時間長
import numpy as np
# TS 38.211 clause 4.1: Tc = 1/(480e3 * 4096) s, kappa = 64
TC = 1 / (480e3 * 4096)
KAPPA = 64
print(" mu SCS_kHz slots/sf slot_us Nu_us CP_us CPlong_us CP_ext_us")
for mu in range(7):
scs_khz = 15 * 2 ** mu
nu = 2048 * KAPPA * 2.0 ** -mu * TC # useful symbol length
cp = 144 * KAPPA * 2.0 ** -mu * TC # normal CP, l != 0 and l != 7*2^mu
cp_long = cp + 16 * KAPPA * TC # normal CP, l = 0 or l = 7*2^mu
cp_ext = 512 * KAPPA * 2.0 ** -mu * TC if mu == 2 else float("nan")
slots = 2 ** mu
slot_us = 1e3 / slots
print(f"{mu:3d} {scs_khz:7d} {slots:8d} {slot_us:8.2f} {nu*1e6:6.2f} {cp*1e6:6.3f} {cp_long*1e6:9.3f} {cp_ext*1e6:9.3f}")
# Check: 14 symbols (with two long CPs per half-subframe) fill exactly 0.5 ms per 7*2^mu symbols
for mu in range(7):
n_half = 7 * 2 ** mu
total = sum((2048 * KAPPA * 2.0 ** -mu + 144 * KAPPA * 2.0 ** -mu + (16 * KAPPA if l == 0 else 0)) * TC
for l in range(n_half))
assert abs(total - 0.5e-3) < 1e-12, (mu, total)
print("each 0.5 ms half-subframe is filled exactly for mu = 0..6")
# Sample rate for a chosen FFT size: fs = N_fft * SCS
for scs_khz, n_fft in [(15, 2048), (30, 4096), (30, 1024), (120, 4096)]:
print(f"SCS {scs_khz} kHz, FFT {n_fft}: fs = {n_fft * scs_khz / 1e3:.2f} Msample/s")
期待される出力は次のとおりです。
mu SCS_kHz slots/sf slot_us Nu_us CP_us CPlong_us CP_ext_us
0 15 1 1000.00 66.67 4.688 5.208 nan
1 30 2 500.00 33.33 2.344 2.865 nan
2 60 4 250.00 16.67 1.172 1.693 4.167
3 120 8 125.00 8.33 0.586 1.107 nan
4 240 16 62.50 4.17 0.293 0.814 nan
5 480 32 31.25 2.08 0.146 0.667 nan
6 960 64 15.62 1.04 0.073 0.594 nan
each 0.5 ms half-subframe is filled exactly for mu = 0..6
SCS 15 kHz, FFT 2048: fs = 30.72 Msample/s
SCS 30 kHz, FFT 4096: fs = 122.88 Msample/s
SCS 30 kHz, FFT 1024: fs = 30.72 Msample/s
SCS 120 kHz, FFT 4096: fs = 491.52 Msample/s
コード: マルチパスチャネルを通る1つのOFDMシンボル
30.72 Msample/sでの30 kHz・1024ポイントのシンボルは、QPSKで変調した612本のサブキャリア(51リソースブロック、30 kHzの20 MHzの欄に相当)を運びます。サンプルはcomplex128です。サイクリックプレフィックスより短い9タップのチャネルは、サブキャリアごとに1回の複素除算で正確に打ち消せます。
import numpy as np
rng = np.random.default_rng(7)
n_fft, n_cp, n_used = 1024, 72, 612 # 30 kHz SCS -> fs = 30.72 Msample/s, 51 RB x 12 = 612 subcarriers
fs = n_fft * 30e3
qpsk = (rng.choice([-1, 1], n_used) + 1j * rng.choice([-1, 1], n_used)) / np.sqrt(2)
grid = np.zeros(n_fft, dtype=np.complex128)
k = np.r_[1:n_used // 2 + 1, n_fft - n_used // 2:n_fft] # skip DC, fill both edges
grid[k] = qpsk
x = np.fft.ifft(grid) * np.sqrt(n_fft)
tx = np.concatenate([x[-n_cp:], x]) # prepend cyclic prefix
h = np.array([1.0, 0, 0, 0.5j, 0, 0, 0, 0, 0.25]) # 9-tap channel, shorter than the CP
rx = np.convolve(tx, h)[: tx.size]
y = np.fft.fft(rx[n_cp:]) / np.sqrt(n_fft)
H = np.fft.fft(h, n_fft)
eq = y[k] / H[k] # one-tap equaliser per subcarrier
print(f"fs = {fs/1e6:.2f} Msample/s, CP = {n_cp/fs*1e6:.2f} us, channel span = {(h.size-1)/fs*1e6:.2f} us")
print(f"max error after one-tap equalisation: {np.max(np.abs(eq - qpsk)):.2e}")
print(f"CP overhead: {n_cp / (n_fft + n_cp) * 100:.1f} %")
期待される出力は次のとおりです。
fs = 30.72 Msample/s, CP = 2.34 us, channel span = 0.26 us
max error after one-tap equalisation: 1.02e-15
CP overhead: 6.6 %
30.72 Msample/sでの72サンプルのプレフィックスは、30 kHzにおけるNRのノーマルCPです。hを73タップより長くすると、符号間干渉が入り込むため誤差が急増します。
落とし穴
- すべてのスロットを1 msとみなすこと。サブフレームあたり1スロットなのはμ = 0だけです。
- 各ハーフサブフレームの先頭シンボルにある長いCPを忘れること。全体で1種類のCP長を使うと、シンボルの開始時刻が徐々にずれます。
- 誤った周波数レンジのN_RBを読むこと。FR1とFR2の表は異なります。
- SS/PBCHブロックのサブキャリア間隔とデータのサブキャリア間隔を混同すること。同じキャリア上でも両者が異なる場合があります。
- リリースの機能一覧を、ネットワークが実際に運用している内容とみなすこと。通信事業者は機能を選択的に有効にします。
出典
- 3GPP TS 38.211、4章と5.3節。ヌメロロジー、フレーム構造、OFDMシンボル生成。
- 3GPP TS 38.101-1とTS 38.101-2、それぞれのTable 5.3.2-1。
- 3GPP TS 38.104、Table 5.1-1、周波数レンジ。
- 3GPP TS 38.213、4.1節、SS/PBCHブロックのケース。
- 3GPP TS 36.211、LTEのフレーム構造とサイクリックプレフィックス長。
- 用語集: OFDMA、PAPR、5G NR、LTE。