フラクショナルN周波数シンセサイザの理論と導出と実装

スマートフォンが LTE の 800 MHz バンドから 2.1 GHz バンドへ、そして Wi-Fi の 5.8 GHz へと、ほんの数ミリ秒で正確な局部発振周波数を切り替えられるのはなぜでしょうか。あるいは、放送局がチャンネルごとに 6 MHz 刻みでなく数十 kHz の細かい刻みで正確なキャリアを生成できるのはどうしてでしょうか。これらの裏側には、たった一つの高安定な水晶基準発振器から任意の周波数を「合成」する周波数シンセサイザ(frequency synthesizer)という回路が存在します。

その中でも現代の無線機でほぼ標準的に使われるのが フラクショナルN(fractional-N)周波数シンセサイザ です。整数分周のシンセサイザでは「周波数分解能を細かくすると応答が遅く位相雑音も悪化する」という根本的なトレードオフがありました。フラクショナルN は、分周比を整数でなく「平均として小数」にすることでこの壁を突破します。しかしそのままでは規則的なスプリアス(不要なスペクトル線)が大量に発生してしまう — この問題を デルタシグマ変調(delta-sigma modulation) による分周比のディザリングと量子化雑音整形(noise shaping)で解決するのが、本記事の中心テーマです。

フラクショナルN シンセサイザを理解すると、以下のような分野への見通しが一気に開けます。

  • 無線通信(5G・Wi-Fi・衛星通信): 局部発振器(LO)の周波数を細かく・高速に切り替えながら、低位相雑音を維持するための中核技術です
  • 計測器(シグナルジェネレータ・スペクトラムアナライザ): 任意の周波数を高分解能で生成するためにフラクショナルN PLL が不可欠です
  • クロック生成(FPGA・SoC・データコンバータ): 任意の基準クロックから所望のシステムクロックを合成する用途で、デルタシグマ分周が広く使われます

本記事の内容

  • 周波数シンセサイザの基本と整数N分周の分解能の限界
  • フラクショナルN の基本アイデア(分周比の時間平均)の導出
  • 単純な小数分周が生むフラクショナルスプリアスの正体
  • デルタシグマ変調による分周比ディザリングと量子化雑音整形の導出
  • MASH 構造による高次ノイズシェーピングの仕組み
  • シンセサイザ全体の位相雑音バジェットと量子化雑音の寄与
  • Python 実装: スプリアスの可視化、デルタシグマのノイズシェーピング、位相雑音スペクトルの合成

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

PLL のループ伝達関数とロックの概念、および VCO の位相雑音の振る舞いを前提とします。これらが頭に入っていれば、フラクショナルN がなぜ位相雑音と分解能のトレードオフを解消できるのかが直感的に理解できます。

周波数シンセサイザとは

基準発振器から任意の周波数を作る

無線機には「正確な周波数」が欠かせません。送受信のキャリア周波数がずれれば隣のチャンネルに漏れ込み、復調もできなくなります。しかし、任意の周波数を直接、高い安定度で発振させるのは困難です。安定度が高い発振器といえば水晶発振器ですが、水晶は特定の周波数(たとえば 10 MHz や 40 MHz)でしか正確に発振しません。

そこで発想を変えます。「正確だが周波数が固定の基準」を一つ用意し、そこから「正確で、しかも周波数を自由に選べる出力」を作り出す — これが周波数シンセサイザの役割です。たとえるなら、正確に時を刻む一つのメトロノーム(基準発振器)から、その整数倍や分数倍のテンポを電子的に作り出す装置だと考えてください。

PLLによる周波数合成の枠組み

最も広く使われる方式が PLL(位相同期回路)ベースの周波数合成です。基本構成は次の要素からなります。

  • 基準発振器: 水晶などの高安定発振器。周波数 $f_{\text{ref}}$
  • 基準分周器(R分周): 基準を $R$ 分周し、位相比較周波数 $f_{\text{PFD}} = f_{\text{ref}}/R$ を作る
  • 位相周波数比較器(PFD): 基準と帰還信号の位相差を検出する
  • チャージポンプ + ループフィルタ: 位相差を制御電圧に変換する
  • 電圧制御発振器(VCO): 制御電圧で出力周波数 $f_{\text{out}}$ を変える
  • 帰還分周器(N分周): VCO 出力を $N$ 分周して PFD に戻す

ループがロックすると、PFD に入る 2 つの信号の周波数が等しくなります。すなわち、

$$ \frac{f_{\text{out}}}{N} = f_{\text{PFD}} = \frac{f_{\text{ref}}}{R} $$

これを $f_{\text{out}}$ について解くと、シンセサイザの基本式が得られます。

$$ f_{\text{out}} = N \cdot f_{\text{PFD}} = \frac{N}{R} f_{\text{ref}} $$

つまり、出力周波数は分周比 $N$ によって決まります。$R$ を固定して $N$ を変えれば、出力周波数を $f_{\text{PFD}}$ きざみで選べるわけです。

ここで一つの重大な制約が顔を出します。$N$ は分周器の性質上、整数でなければなりません。次節では、この「整数しか取れない」という制約が周波数分解能と PLL の性能にどんな限界を課すのかを掘り下げます。

整数N分周の限界

周波数分解能はPFD周波数に等しい

整数N シンセサイザでは、$N$ を 1 だけ変えると出力周波数は $f_{\text{PFD}}$ だけ動きます。

$$ \Delta f_{\text{out}} = (N+1)f_{\text{PFD}} – N f_{\text{PFD}} = f_{\text{PFD}} $$

したがって 周波数分解能(チャネル間隔)は PFD 周波数そのもの になります。たとえば 100 kHz きざみで周波数を選びたければ、$f_{\text{PFD}} = 100$ kHz にしなければなりません。

分解能を上げると何が悪化するのか

「細かい分解能が欲しければ $f_{\text{PFD}}$ を小さくすればよい」と思うかもしれません。しかし、$f_{\text{PFD}}$ を小さくすると深刻な副作用が 3 つ生じます。

第一に、ループ帯域が狭くなります。PLL のループ帯域は安定性の観点から $f_{\text{PFD}}$ のおよそ 1/10 以下に取るのが定石です。$f_{\text{PFD}}$ が 100 kHz なら帯域はせいぜい 10 kHz 程度になり、周波数の切り替え(ロックアップ)に時間がかかります。高速にチャネルを切り替えたい用途では致命的です。

第二に、VCO の位相雑音が支配的な領域が広がります。PLL はループ帯域内では VCO の位相雑音を抑圧しますが、帯域外では VCO 本来の雑音がそのまま出ます。帯域が狭いほど、VCO 雑音が抑圧されずに残る領域が広くなり、近傍位相雑音が悪化します。

第三に、分周比 $N$ が大きくなります。出力周波数を一定とすれば $N = f_{\text{out}}/f_{\text{PFD}}$ なので、$f_{\text{PFD}}$ を小さくすると $N$ が大きくなります。ここが本質的に重要な点です。PFD やチャージポンプの位相雑音、基準発振器の位相雑音は、出力に現れるとき $N$ 倍(電力で $N^2$ 倍)に増幅されます。これを N倍ノイズ増倍(in-band noise multiplication) と呼びます。

N倍ノイズ増倍の導出

帰還分周器は VCO 出力の位相を $1/N$ にします。逆に、PFD 入力換算の位相雑音を出力に換算するときは $N$ 倍になります。PLL がループ帯域内(PFD の雑音が支配する領域)でロックしているとき、PFD 入力に換算した位相雑音電力スペクトル密度を $S_{\phi,\text{in}}(f)$ とすると、出力の位相雑音は次のようになります。

$$ S_{\phi,\text{out}}(f) = N^2 \, S_{\phi,\text{in}}(f) \quad (\text{ループ帯域内}) $$

これをデシベル表記にすると、

$$ \mathcal{L}_{\text{out}}(f) = \mathcal{L}_{\text{in}}(f) + 20\log_{10} N \ \text{[dB]} $$

たとえば 2 GHz 出力で $f_{\text{PFD}} = 100$ kHz とすると $N = 20000$、$20\log_{10}(20000) \approx 86$ dB もの増幅です。一方、もし $f_{\text{PFD}} = 20$ MHz が使えれば $N = 100$、増幅はわずか 40 dB で済みます。つまり、PFD 周波数を高く保てるほど近傍位相雑音は良くなるのです。

ここに整数N シンセサイザの根本的なジレンマがあります。細かい分解能のためには $f_{\text{PFD}}$ を小さくしたいが、低位相雑音・高速ロックのためには $f_{\text{PFD}}$ を大きくしたい。両者は真っ向から対立します。この矛盾を解くのがフラクショナルN です。次節でその核心的なアイデアを見ましょう。

フラクショナルNの基本アイデア

分周比を「平均として小数」にする

整数N の制約は「$N$ が整数でなければならない」ことでした。では、分周比を時間とともに $N$ と $N+1$ の間で切り替え、その時間平均を小数にできないでしょうか。

具体例で考えましょう。分周比を 8 回中 5 回は $N=10$、3 回は $N=11$ に設定したとします。8 回の PFD 周期で VCO は合計 $5 \times 10 + 3 \times 11 = 83$ 回振動します。したがって平均分周比は、

$$ N_{\text{avg}} = \frac{5 \times 10 + 3 \times 11}{8} = \frac{83}{8} = 10.375 $$

となり、整数では作れない 10.375 という分周比が実現できました。出力周波数は、

$$ f_{\text{out}} = N_{\text{avg}} \cdot f_{\text{PFD}} = 10.375 \, f_{\text{PFD}} $$

です。重要なのは、この平均分周比を実現するのに $f_{\text{PFD}}$ を小さくする必要が一切ないことです。$f_{\text{PFD}}$ を高く保ったまま、出力周波数を $f_{\text{PFD}}$ よりはるかに細かい刻みで設定できます。

一般化したフラクショナルN分周比

整数部 $N_{\text{int}}$ と小数部 $F/M$($F$ は分子、$M$ は法、$0 \le F < M$)を用いて、平均分周比を次のように書きます。

$$ N_{\text{avg}} = N_{\text{int}} + \frac{F}{M} $$

このとき出力周波数は、

$$ f_{\text{out}} = \left(N_{\text{int}} + \frac{F}{M}\right) f_{\text{PFD}} $$

周波数分解能(最小の刻み)は、$F$ を 1 だけ変えたときの変化量です。

$$ \Delta f_{\text{out}} = \frac{1}{M} f_{\text{PFD}} $$

法 $M$ を大きくとれば(たとえば $M = 2^{24}$)、分解能は $f_{\text{PFD}}$ の数百万分の一にまで細かくできます。これがフラクショナルN の威力です。たとえば $f_{\text{PFD}} = 20$ MHz でも、$M = 2^{24} \approx 1.7\times10^7$ なら分解能は約 1.2 Hz に達します。$f_{\text{PFD}}$ を高く保てるので $N$ が小さく、近傍位相雑音も良好です。

アキュムレータによる分周比の制御

平均として $F/M$ を実現するには、各 PFD 周期で「$N_{\text{int}}$ にするか $N_{\text{int}}+1$ にするか」を決める仕組みが必要です。古典的には アキュムレータ(accumulator) を使います。

法 $M$ のアキュムレータに、毎周期 $F$ を加算します。アキュムレータの値が $M$ を超えたら、オーバーフローが発生して $M$ を引き、その周期だけ分周比を 1 だけ増やします($N_{\text{int}} \to N_{\text{int}}+1$)。アキュムレータ値 $a[k]$ は次の漸化式に従います。

$$ a[k] = (a[k-1] + F) \bmod M $$

オーバーフロー(キャリー)$c[k]$ は、

$$ c[k] = \left\lfloor \frac{a[k-1] + F}{M} \right\rfloor \in \{0, 1\} $$

長い目で見ると、$M$ 周期ごとにちょうど $F$ 回のオーバーフローが起きるので、オーバーフローの平均発生率は $F/M$ となり、平均分周比はめでたく $N_{\text{int}} + F/M$ になります。

しかし、ここに落とし穴があります。アキュムレータのオーバーフローは周期的に起こります。この規則性こそが、次節で見るフラクショナルスプリアスを生む元凶なのです。

フラクショナルスプリアスの正体

瞬時位相誤差の蓄積

平均分周比は小数でも、各瞬間の分周比は $N_{\text{int}}$ か $N_{\text{int}}+1$ の整数です。したがって瞬間瞬間では、VCO の実際の位相と「理想的に $N_{\text{avg}}$ で割った位相」との間にズレが生じます。このズレを 瞬時位相誤差 と呼びます。

分周比を $N_{\text{int}}$ にしている周期では、本来 $N_{\text{int}}+F/M$ で割るべきところを少なめに割っているので、帰還信号の位相が理想より進みます。逆にオーバーフローで $N_{\text{int}}+1$ にした周期では位相が戻ります。アキュムレータ値 $a[k]$ は、まさにこの「蓄積された位相誤差」に比例した量です。

$f_{\text{PFD}}$ の 1 周期あたり、位相誤差は $2\pi/M$ きざみで増減します。アキュムレータが 0 から $M$ へ向かってのこぎり波状に増加し、オーバーフローで一気に戻る — こののこぎり波状の位相誤差が PFD で検出され、VCO の制御電圧を周期的に揺さぶります。

スプリアス周波数の導出

アキュムレータののこぎり波の繰り返し周期を考えましょう。アキュムレータは毎周期 $F$ ずつ増え、$M$ で一巡します。$F$ と $M$ の最大公約数を $g = \gcd(F, M)$ とすると、のこぎり波の基本周期は、

$$ T_{\text{spur}} = \frac{M/g}{f_{\text{PFD}}} \quad \text{(PFD周期の } M/g \text{ 倍)} $$

したがって、最低次のフラクショナルスプリアスは出力キャリアから次の周波数オフセットに現れます。

$$ f_{\text{spur}} = \frac{g}{M} f_{\text{PFD}} = \gcd(F, M) \cdot \Delta f_{\text{out}} $$

特に $\gcd(F, M)=1$ のとき、スプリアスは $\Delta f_{\text{out}} = f_{\text{PFD}}/M$ のオフセットに現れます。問題は、このオフセットがしばしばループ帯域内に入ることです。たとえば $F/M$ が 1/2 や 1/4 のような単純な分数だと、$g$ が大きくなりスプリアスがキャリア近傍の数 kHz〜数十 kHz に立ち、ループフィルタで除去しきれず出力に漏れます。

なぜディザリングが必要か

問題の本質は「位相誤差が周期的である」ことです。周期的な信号は離散的なスペクトル線(スプリアス)を生みます。もし位相誤差をランダムにできれば、スペクトルは離散線ではなく連続した雑音床(ノイズフロア)に散らばり、特定の周波数に立つ鋭いスプリアスは消えます。

最も素朴なアイデアは、オーバーフローのタイミングを乱数で揺さぶる「ランダムディザリング」です。これでスプリアスは消えますが、加えた乱数がそのまま位相雑音として全帯域に広がってしまい、近傍位相雑音が悪化します。雑音を「平坦にばらまく」のではなく、PLL のループフィルタが除去しやすい高周波側に追いやりたい — この要求に応えるのがデルタシグマ変調です。次節で核心に入りましょう。

デルタシグマ変調によるノイズシェーピング

量子化としての分周比選択

フラクショナルN の分周比選択は、本質的に「小数 $F/M$ を整数列 $\{0, 1\}$(あるいは $N_{\text{int}}$ への加算値)で表現する」量子化問題です。デルタシグマ変調は、まさにこの量子化を「量子化誤差を高周波側に追いやる」ように行う技術です。

入力をフラクショナル設定値 $x = F/M$($0 \le x < 1$ の定数)とし、各 PFD 周期で整数出力 $y[k] \in \{0, 1, \dots\}$(分周比への加算値)を生成します。出力の時間平均が $x$ に一致しつつ、瞬時誤差のスペクトルが整形されるのが目標です。

1次デルタシグマ変調器の構造と導出

最もシンプルな 1 次(first-order)デルタシグマ変調器は、実は前述のアキュムレータそのものと等価です。構成は「積分器(アキュムレータ)+ 量子化器(オーバーフロー判定)+ 帰還」です。

時刻 $k$ における動作を式で追います。アキュムレータの状態を $u[k]$、出力を $y[k]$ とすると、

$$ u[k] = u[k-1] + x – y[k-1] $$

$$ y[k] = Q(u[k]) = \lfloor u[k] \rfloor \ \text{または} \ \lceil u[k] \rceil $$

ここで $Q(\cdot)$ は量子化器で、量子化誤差を $e[k] = y[k] – u[k]$ と定義します。1 次変調器では出力が直接アキュムレータに帰還され、誤差が積分されていきます。

量子化誤差を独立な白色雑音とみなす 線形化モデル(量子化雑音を加法的白色雑音 $e[k]$ で近似する)を使うと、出力は次のように書けます。前式から $y[k] = u[k] + e[k]$ で、これに $u[k] = u[k-1] + x – y[k-1]$ を代入します。

$$ y[k] = u[k-1] + x – y[k-1] + e[k] $$

$z$ 変換すると($u[k-1] \to z^{-1}U(z)$ など)、定常入力 $x$ の項は信号成分としてまとめられ、量子化雑音に着目した伝達特性が次のように整理されます。1 次変調器の出力は、

$$ Y(z) = X(z) + (1 – z^{-1}) E(z) $$

という形に帰着します。第 1 項 $X(z)$ が信号(そのまま通る)、第 2 項の係数 $(1 – z^{-1})$ が 雑音伝達関数(NTF: Noise Transfer Function) です。

ノイズシェーピングの周波数特性

NTF の周波数特性を見ましょう。$z = e^{j2\pi f / f_{\text{PFD}}}$ を代入すると、

$$ \text{NTF}(z) = 1 – z^{-1} = 1 – e^{-j2\pi f/f_{\text{PFD}}} $$

この大きさの二乗を求めます。オイラーの公式 $e^{-j\theta} = \cos\theta – j\sin\theta$ を使い、$\theta = 2\pi f/f_{\text{PFD}}$ とおくと、

$$ |1 – e^{-j\theta}|^2 = (1-\cos\theta)^2 + \sin^2\theta = 2 – 2\cos\theta = 4\sin^2\!\left(\frac{\theta}{2}\right) $$

ここで三角関数の半角公式 $1-\cos\theta = 2\sin^2(\theta/2)$ を使いました。したがって NTF の振幅は、

$$ |\text{NTF}(f)| = 2\left|\sin\!\left(\frac{\pi f}{f_{\text{PFD}}}\right)\right| $$

この関数は低周波($f \to 0$)でゼロに近づき、$f = f_{\text{PFD}}/2$ で最大値 2 をとります。つまり、量子化雑音は低周波ではほとんどゼロに抑えられ、高周波側に押しやられます。これがノイズシェーピングです。低周波(キャリア近傍)の量子化雑音が抑圧される一方、高周波側に追いやられた雑音は PLL のループフィルタ(低域通過特性)で除去されます。

量子化雑音電力スペクトル密度

量子化器のステップを 1(分周比の単位)とすると、量子化誤差 $e[k]$ は区間 $[-1/2, 1/2]$ に一様分布する白色雑音と近似でき、その分散は、

$$ \sigma_e^2 = \frac{1}{12} $$

です(一様分布 $[-\Delta/2, \Delta/2]$ の分散は $\Delta^2/12$、ここで $\Delta=1$)。サンプリング周波数 $f_{\text{PFD}}$ で、ナイキスト帯域 $[0, f_{\text{PFD}}/2]$ に白色雑音電力が均等に分布するので、片側電力スペクトル密度は、

$$ S_e(f) = \frac{\sigma_e^2}{f_{\text{PFD}}/2} \cdot \frac{1}{2}= \frac{1}{12 f_{\text{PFD}}} \quad \text{(分周比$^2$/Hz)} $$

これに NTF の二乗をかけたものが、整形後の量子化雑音スペクトルです。$L$ 次のデルタシグマでは NTF が $(1-z^{-1})^L$ になるので、

$$ S_{q,L}(f) = S_e(f) \cdot |1 – z^{-1}|^{2L} = \frac{1}{12 f_{\text{PFD}}}\left[2\sin\!\left(\frac{\pi f}{f_{\text{PFD}}}\right)\right]^{2L} $$

低周波では $\sin(\pi f/f_{\text{PFD}}) \approx \pi f/f_{\text{PFD}}$ と近似でき、

$$ S_{q,L}(f) \approx \frac{1}{12 f_{\text{PFD}}}\left(\frac{2\pi f}{f_{\text{PFD}}}\right)^{2L} $$

となります。$f^{2L}$ で増加するので、次数 $L$ が高いほどキャリア近傍の雑音は急峻に抑えられます。1 次なら $f^2$(20 dB/dec)、2 次なら $f^4$(40 dB/dec)、3 次なら $f^6$(60 dB/dec)です。

分周比のゆらぎから位相雑音への変換

最後に、分周比のゆらぎが出力位相雑音にどう変換されるかを導きます。分周比が瞬時に理想値から $\delta N[k]$ だけずれると、PFD 1 周期あたりの位相誤差は $2\pi \, \delta N[k] / N_{\text{avg}}$ ……ではなく、より正確には、分周比のゆらぎは VCO の位相を $2\pi \, \delta N[k]$ ラジアン分、PFD 換算で揺さぶります。出力換算では、量子化雑音 PSD(分周比$^2$/Hz)に $(2\pi)^2$ を掛けると位相雑音 PSD(rad$^2$/Hz)になります。

$$ S_{\phi,\Delta\Sigma}(f) = (2\pi)^2 \, S_{q,L}(f) = \frac{(2\pi)^2}{12 f_{\text{PFD}}}\left[2\sin\!\left(\frac{\pi f}{f_{\text{PFD}}}\right)\right]^{2L} $$

この位相雑音はループフィルタの低域通過特性 $|H_{\text{LP}}(f)|^2$ を通って出力に現れるので、最終的な寄与は $S_{\phi,\Delta\Sigma}(f)\,|H_{\text{LP}}(f)|^2$ です。ノイズシェーピングで高周波に追いやられた雑音をループフィルタが削ぎ落とす — この二段構えがフラクショナルN の低位相雑音を支えています。

導出が一段落しました。実用上は 1 次変調器だけでは不十分なことが多く、高次のノイズシェーピングが求められます。次節では、ハードウェアで安定に高次を実現する MASH 構造を見ましょう。

MASH構造による高次ノイズシェーピング

高次変調器の安定性問題

ノイズシェーピングの効果は次数 $L$ とともに高まりますが、単純に積分器を縦続接続した高次デルタシグマ変調器は不安定になりやすいという問題があります。積分器が飽和し、出力が発振的に振る舞ってしまうのです。

これを回避する巧妙な構成が MASH(Multi-stAge noise SHaping) です。MASH は、1 次変調器(=アキュムレータ)を複数段カスケードし、各段は前段の量子化誤差を入力として受け取ります。1 次変調器は常に安定なので、それを組み合わせる MASH も安定です。

MASH 1-1-1(3次)の導出

3 段の MASH(MASH 1-1-1)を考えます。第 1 段は入力 $x$ を受け、出力 $y_1$ と量子化誤差 $e_1$ を生成します。線形化モデルで、

$$ Y_1(z) = X(z) + (1 – z^{-1})E_1(z) $$

第 2 段は第 1 段の誤差 $-e_1$(符号は構成による)を入力とし、

$$ Y_2(z) = -E_1(z) + (1 – z^{-1})E_2(z) $$

第 3 段は第 2 段の誤差を入力とし、

$$ Y_3(z) = -E_2(z) + (1 – z^{-1})E_3(z) $$

これらを、各段出力に微分器 $(1-z^{-1})$ を順に掛けて足し合わせる「誤差キャンセルネットワーク」で結合します。最終出力 $Y(z)$ は、

$$ Y(z) = Y_1(z) + (1 – z^{-1})Y_2(z) + (1 – z^{-1})^2 Y_3(z) $$

ここに各段の式を代入していきます。まず第 1 段と第 2 段の寄与を見ると、$Y_1$ の誤差項 $(1-z^{-1})E_1$ と、$(1-z^{-1})Y_2$ に含まれる $-(1-z^{-1})E_1$ がちょうど打ち消し合います。

$$ Y_1 + (1-z^{-1})Y_2 = X + (1-z^{-1})E_1 + (1-z^{-1})[-E_1 + (1-z^{-1})E_2] $$

$(1-z^{-1})E_1$ の項が相殺され、

$$ = X + (1-z^{-1})^2 E_2 $$

同様に、第 3 段の項 $(1-z^{-1})^2 Y_3 = (1-z^{-1})^2[-E_2 + (1-z^{-1})E_3]$ を加えると、$(1-z^{-1})^2 E_2$ の項が相殺されます。

$$ Y(z) = X(z) + (1 – z^{-1})^3 E_3(z) $$

見事に、中間段の量子化誤差 $E_1, E_2$ が完全にキャンセルされ、最終段の誤差 $E_3$ だけが 3 次の NTF $(1-z^{-1})^3$ で整形されて残ります。これが MASH の核心です。各段は安定な 1 次変調器のままで、全体として 3 次のノイズシェーピング(60 dB/dec)が得られます。

MASH出力のレンジ

MASH 1-1-1 の出力 $y[k]$ は、誤差キャンセルネットワークの構成上、$\{-3, -2, -1, 0, 1, 2, 3, 4\}$ といった複数値($0$ や $1$ だけでなく)をとります。これは瞬時分周比が $N_{\text{int}}$ の近傍で $\pm$ 数段にわたって変動することを意味し、整数N に比べて広い分周比レンジを瞬時的に使うため、VCO の制御範囲やループフィルタ設計に影響します。瞬時分周比の変動が大きいほど高周波の量子化雑音も大きくなるため、次数を上げすぎると逆効果になる場合もあり、実用では 2〜4 次が選ばれます。

ここまでで、デルタシグマと MASH によりスプリアスを雑音床に変え、その雑音床を高周波に整形する仕組みを理解しました。次は、これらが全体の位相雑音バジェットの中でどう位置づけられるかを俯瞰します。

位相雑音バジェット

主要な雑音源

フラクショナルN シンセサイザの出力位相雑音は、複数の独立な雑音源の重ね合わせです。代表的な寄与を、出力換算(オフセット周波数 $f$ の関数)でまとめます。

  • 基準発振器の雑音: $(N/R)^2$ 倍されてループ帯域内に現れる
  • PFD・チャージポンプの雑音: $N^2$ 倍されてループ帯域内に現れる(フリッカと白色)
  • VCO の雑音: ループ帯域外で支配的。Leeson の式に従い $1/f^2$, $1/f^3$ 特性を持つ
  • デルタシグマ量子化雑音: $(1-z^{-1})^{2L}$ で整形され、ループフィルタ通過後に高周波側に残る

各雑音は独立とみなせるので、位相雑音 PSD は単純に足し合わせられます。

$$ S_{\phi,\text{out}}(f) = N^2 S_{\phi,\text{PFD}}(f)|H(f)|^2 + S_{\phi,\text{VCO}}(f)|1-H(f)|^2 + S_{\phi,\Delta\Sigma}(f)|H(f)|^2 $$

ここで $H(f)$ は基準から出力への閉ループ伝達関数(低域通過特性)、$1-H(f)$ は VCO から出力への伝達関数(高域通過特性)です。

ループ帯域の最適化

この式から、ループ帯域 $f_c$ の選び方が見えてきます。ループ帯域内では PFD・基準雑音($N^2$ 倍)が支配し、帯域外では VCO 雑音が支配します。両者が交差する点付近にループ帯域を設定すると、全帯域での位相雑音積分(積分ジッタ)が最小になります。

一方、デルタシグマ量子化雑音は $H(f)$(低域通過)を通るため、ループ帯域 $f_c$ より高い周波数では急速に削られます。デルタシグマの次数 $L$ とループ次数を適切に組み合わせ、$f > f_c$ で量子化雑音が VCO 雑音床より十分下に来るよう設計します。一般に、ループフィルタの次数はデルタシグマの次数 $L$ に対し $L$ 次以上の減衰を持たせる必要があります。そうしないと、高周波に追いやった量子化雑音が十分に減衰されず、遠方位相雑音を持ち上げてしまいます。

整数N比較での優位性

フラクショナルN の最大の利点は、同じ出力分解能を得るのに $f_{\text{PFD}}$ を大幅に高くできる点です。前述のとおり $N$ が小さくなるため、$N^2$ で増幅される PFD・基準雑音が劇的に下がります。たとえば $f_{\text{PFD}}$ を 100 kHz から 20 MHz へ 200 倍にできれば、$20\log_{10}(200) \approx 46$ dB もの近傍位相雑音改善が原理的に可能です。デルタシグマ量子化雑音という新たな雑音源を導入する代償はありますが、ノイズシェーピングとループフィルタでキャリア近傍では十分小さく抑えられるため、トータルでは大きな改善になります。

理論はここまでです。次は Python で、整数N の分解能限界、デルタシグマのノイズシェーピング、そしてスプリアスから雑音床への変化を実際に可視化して、これまでの導出を体感しましょう。

Pythonによる実装と可視化

フラクショナルスプリアスとディザリングの比較

まず、単純なアキュムレータ(1 次デルタシグマ相当だが、ここでは比較のため周期的なのこぎり波として扱う)が生む位相誤差と、1 次デルタシグマの出力を比較し、位相誤差のスペクトルにスプリアスが立つ様子を見ます。

import numpy as np
import matplotlib.pyplot as plt

# シミュレーション設定
f_pfd = 20e6        # PFD周波数 [Hz]
M = 2**10           # 法(分解能パラメータ)
F = 100             # 小数分子(F/M が小数部)
n_samples = 2**16   # サンプル数

# --- 単純アキュムレータ(周期的)---
acc = 0
phase_err_acc = np.zeros(n_samples)  # 蓄積位相誤差(アキュムレータ値)
for k in range(n_samples):
    acc_next = acc + F
    carry = acc_next // M            # オーバーフロー(0 or 1)
    acc = acc_next % M
    phase_err_acc[k] = acc / M       # 0〜1 に正規化した瞬時位相誤差

print(f"平均キャリー率(=F/M): {F/M:.4f}")
print(f"アキュムレータ位相誤差の周期: {M // np.gcd(F, M)} PFDサイクル")

このコードは法 $M$ のアキュムレータに毎周期 $F$ を加算し、その正規化値(蓄積位相誤差)を記録します。出力されるキャリー率は $F/M$ に一致し、位相誤差はのこぎり波状に $M/\gcd(F,M)$ 周期で繰り返すことが確認できます。この周期性こそがスプリアスの原因です。

次に、同じ $F/M$ を 1 次デルタシグマ変調器で実現し、出力系列と量子化誤差を記録します。

# --- 1次デルタシグマ変調器 ---
x = F / M                  # 入力(小数部)
u = 0.0                    # 積分器(アキュムレータ状態)
y_seq = np.zeros(n_samples)   # 出力(分周比への加算値: 0 or 1)
phase_err_ds = np.zeros(n_samples)  # 量子化誤差(位相誤差に相当)
for k in range(n_samples):
    u = u + x              # 積分
    y = np.floor(u)        # 量子化(オーバーフロー判定)
    u = u - y              # 帰還(誤差を残す)
    y_seq[k] = y
    phase_err_ds[k] = u    # 残った小数部 = 瞬時位相誤差

print(f"DS出力の平均(=F/M): {y_seq.mean():.4f}")
print(f"DS出力の取りうる値: {np.unique(y_seq)}")

1 次デルタシグマでも出力の平均は $F/M$ に一致します。ただし、出力 y_seq は 0 と 1 の 2 値で、その瞬時パターンが入力値に応じて決まります。残った積分器の値 phase_err_ds が瞬時位相誤差に相当し、これが整形される対象です。

位相誤差スペクトルの比較

両者の位相誤差をパワースペクトルで比較し、スプリアスと雑音床の違いを可視化します。

import numpy as np
import matplotlib.pyplot as plt

def psd(signal, fs):
    """片側パワースペクトル密度を簡易計算(窓掛けFFT)"""
    sig = signal - signal.mean()             # DC除去
    win = np.hanning(len(sig))               # ハニング窓
    sig_w = sig * win
    spec = np.fft.rfft(sig_w)
    freqs = np.fft.rfftfreq(len(sig), d=1/fs)
    # 窓の補正を含むPSD
    psd_val = (np.abs(spec)**2) / (fs * np.sum(win**2))
    psd_val[1:] *= 2                          # 片側化
    return freqs, 10*np.log10(psd_val + 1e-20)

f1, p1 = psd(phase_err_acc, f_pfd)
f2, p2 = psd(phase_err_ds, f_pfd)

plt.figure(figsize=(10, 6))
plt.semilogx(f1, p1, label='Simple accumulator (periodic)', alpha=0.8)
plt.semilogx(f2, p2, label='1st-order delta-sigma', alpha=0.8)
plt.xlabel('Offset frequency [Hz]')
plt.ylabel('Phase-error PSD [dB/Hz]')
plt.title('Spur vs. Noise-shaping: phase-error spectrum')
plt.legend()
plt.grid(True, which='both', alpha=0.3)
plt.xlim(f_pfd/n_samples*10, f_pfd/2)
plt.tight_layout()
plt.savefig('frac_n_spur_vs_ds.png', dpi=150, bbox_inches='tight')
plt.show()

このグラフから 2 つの重要な特徴が読み取れます。第一に、単純アキュムレータのスペクトルには鋭いスプリアス(離散的なピーク)が等間隔に立っています。これは位相誤差ののこぎり波が周期的であることの直接の帰結です。第二に、デルタシグマのスペクトルではこれらの鋭いピークが大きく抑えられ、雑音が低周波で小さく高周波で大きい右肩上がりの形(ノイズシェーピング)になっています。スプリアスという「集中したエネルギー」が、扱いやすい「分散した雑音」に変換されたわけです。

ノイズシェーピングの次数依存性

次に、1 次・2 次・3 次(MASH)のデルタシグマを実装し、量子化雑音 PSD の傾き($f^{2L}$)を理論曲線と比較します。

import numpy as np

def mash_delta_sigma(x, n, order):
    """MASH型デルタシグマ変調器。x:入力(0〜1), n:サンプル数, order:次数(1〜3)"""
    # 各段のアキュムレータ状態
    u = np.zeros(order)
    e_prev = np.zeros(order)     # 各段の量子化誤差(前サンプル)
    y_out = np.zeros(n)
    # 誤差キャンセル用の出力履歴(微分器の遅延に使う)
    y_stage_hist = np.zeros((order, 3))
    for k in range(n):
        # 第1段の入力は x、以降は前段の量子化誤差
        inp = x
        y_stages = np.zeros(order)
        for s in range(order):
            u[s] = u[s] + inp        # 積分
            y_s = np.floor(u[s])     # 量子化
            u[s] = u[s] - y_s        # 帰還(誤差を残す)
            y_stages[s] = y_s
            inp = u[s]               # 次段の入力 = この段の量子化誤差
        # 誤差キャンセルネットワーク: sum_s (1-z^-1)^s * y_s
        y_stage_hist = np.roll(y_stage_hist, 1, axis=1)
        y_stage_hist[:, 0] = y_stages
        y = 0.0
        for s in range(order):
            # (1 - z^-1)^s を差分で実装
            if s == 0:
                y += y_stage_hist[0, 0]
            elif s == 1:
                y += y_stage_hist[1, 0] - y_stage_hist[1, 1]
            elif s == 2:
                y += y_stage_hist[2, 0] - 2*y_stage_hist[2, 1] + y_stage_hist[2, 2]
        y_out[k] = y
    return y_out

この関数は order 段の 1 次変調器をカスケードし、誤差キャンセルネットワーク(微分器 $(1-z^{-1})^s$ を差分で実装)で結合します。各段は前段の量子化誤差を入力に取るため、理論どおり中間段の誤差が相殺され、最終段の誤差だけが $(1-z^{-1})^{\text{order}}$ で整形されます。

実行して、出力系列の PSD を理論曲線と重ねます。

import numpy as np
import matplotlib.pyplot as plt

f_pfd = 20e6
n = 2**16
x = 0.3141  # 適当な無理数的小数部(周期性を避ける)

plt.figure(figsize=(10, 6))
colors = ['C0', 'C1', 'C2']
for order in [1, 2, 3]:
    y = mash_delta_sigma(x, n, order)
    freqs, p = psd(y, f_pfd)        # 先に定義した psd 関数を再利用
    plt.semilogx(freqs, p, color=colors[order-1], alpha=0.6,
                 label=f'MASH order {order} (sim)')
    # 理論: S = (1/12/f_pfd) * (2 sin(pi f/f_pfd))^(2*order)
    f_th = freqs[1:]
    S_th = (1/(12*f_pfd)) * (2*np.sin(np.pi*f_th/f_pfd))**(2*order)
    plt.semilogx(f_th, 10*np.log10(S_th), '--', color=colors[order-1], alpha=0.9)

plt.xlabel('Offset frequency [Hz]')
plt.ylabel('Quantization-noise PSD [dB/Hz]')
plt.title('Delta-sigma noise shaping: order dependence (solid=sim, dashed=theory)')
plt.legend()
plt.grid(True, which='both', alpha=0.3)
plt.xlim(f_pfd/n*10, f_pfd/2)
plt.ylim(-160, -40)
plt.tight_layout()
plt.savefig('frac_n_noise_shaping.png', dpi=150, bbox_inches='tight')
plt.show()

このグラフから、シミュレーション(実線)と理論曲線(破線)がよく一致していることが読み取れます。低周波領域で次数 1・2・3 がそれぞれ約 20・40・60 dB/dec の傾きで立ち上がっており、$f^{2L}$ の関係が確認できます。次数が高いほどキャリア近傍(低オフセット)の雑音が深く抑えられる一方、高周波端では次数が高い方が雑音が大きくなっています。これがノイズシェーピングのトレードオフで、ループフィルタで高周波雑音を削ることを前提に設計します。

ループフィルタ通過後の位相雑音スペクトル

最後に、デルタシグマ量子化雑音がループフィルタ(低域通過)を通過した後、VCO 雑音や基準雑音と合成された全体の位相雑音スペクトルを描きます。

import numpy as np
import matplotlib.pyplot as plt

f = np.logspace(2, 7, 1000)   # オフセット周波数 100 Hz 〜 10 MHz
f_pfd = 20e6
fc = 100e3                    # ループ帯域 [Hz]
order_ds = 3                  # デルタシグマ次数

# 閉ループ(基準→出力): 低域通過、2次バターワース近似
H_lp = 1 / (1 + (f/fc)**4) ** 0.5
H_lp2 = H_lp**2               # 電力(|H|^2)

# 1) PFD/基準雑音(N^2倍されてループ帯域内に出る、白色+フリッカ)
N = 100
L_pfd_in = 10**(-150/10) + 10**(-120/10)*(1e3/f)  # 白色 + 1/f
S_ref = N**2 * L_pfd_in * H_lp2

# 2) VCO雑音(Leeson的: 1/f^2, ループ外で支配) * |1-H|^2(高域通過)
L_vco = 10**(-80/10) * (1e4/f)**2     # 1/f^2 近傍
S_vco = L_vco * (1 - H_lp)**2

# 3) デルタシグマ量子化雑音 * |H|^2
S_ds_raw = (2*np.pi)**2/(12*f_pfd) * (2*np.sin(np.pi*f/f_pfd))**(2*order_ds)
S_ds = S_ds_raw * H_lp2

# 合成
S_total = S_ref + S_vco + S_ds

plt.figure(figsize=(10, 6))
plt.semilogx(f, 10*np.log10(S_ref),  '--', label='PFD/Ref ($N^2$, in-band)')
plt.semilogx(f, 10*np.log10(S_vco),  '--', label='VCO (out-of-band)')
plt.semilogx(f, 10*np.log10(S_ds),   '--', label='Delta-sigma (shaped)')
plt.semilogx(f, 10*np.log10(S_total), 'k-', lw=2, label='Total')
plt.axvline(fc, color='gray', ls=':', alpha=0.7, label='Loop BW')
plt.xlabel('Offset frequency [Hz]')
plt.ylabel('Phase noise [dBc/Hz]')
plt.title('Fractional-N synthesizer phase-noise budget')
plt.legend(fontsize=9)
plt.grid(True, which='both', alpha=0.3)
plt.ylim(-180, -60)
plt.tight_layout()
plt.savefig('frac_n_phase_noise_budget.png', dpi=150, bbox_inches='tight')
plt.show()

このグラフから、フラクショナルN シンセサイザの位相雑音の全体像が読み取れます。第一に、ループ帯域(点線)の内側では PFD・基準雑音($N^2$ 倍)が支配し、外側では VCO 雑音が支配する典型的な構造が見えます。両者の交差点付近にループ帯域を置くのが最適です。第二に、デルタシグマ量子化雑音はノイズシェーピングとループフィルタの二重の効果でキャリア近傍では十分小さく抑えられており、合成カーブ(黒)にほとんど寄与していません。これが、フラクショナルN が「細かい分解能」と「低位相雑音」を両立できる理由を視覚的に示しています。次数やループ帯域を変えると、デルタシグマ雜音のカーブが上下に動き、設計上のトレードオフを定量的に把握できます。

まとめ

本記事では、フラクショナルN 周波数シンセサイザの原理を、整数N の限界からデルタシグマ変調によるノイズシェーピングまで、導出を省略せずに解説しました。

  • 整数N の限界: 周波数分解能は PFD 周波数 $f_{\text{PFD}}$ に等しく、細かくすると $N$ が増えて位相雑音が $N^2$ 倍に増幅され、ループ帯域も狭くなる
  • フラクショナルN の核心: 分周比を時間平均として小数 $N_{\text{int}}+F/M$ にすることで、$f_{\text{PFD}}$ を高く保ったまま分解能 $f_{\text{PFD}}/M$ を実現できる
  • フラクショナルスプリアス: 単純なアキュムレータの周期的な位相誤差が離散的なスプリアスを生む
  • デルタシグマ変調: 量子化雑音を NTF $(1-z^{-1})^L$ で整形し、低周波(キャリア近傍)の雑音を高周波側へ追いやる。$S_q \propto f^{2L}$ で抑圧される
  • MASH 構造: 安定な 1 次変調器をカスケードし誤差キャンセルすることで、安定なまま高次ノイズシェーピングを実現する
  • 位相雑音バジェット: PFD・VCO・デルタシグマの各寄与を重ね合わせ、ループ帯域とデルタシグマ次数を最適化する

フラクショナルN は、整数N が抱えた「分解能 vs 位相雑音・速度」の根本的トレードオフを、デルタシグマというデジタル信号処理の発想で解きほぐした美しい技術です。アナログ回路(PLL)とデジタル信号処理(ノイズシェーピング)の融合という点でも、現代の RF 設計を象徴しています。

次のステップとして、以下の記事も参考にしてください。