β: This English translation is in beta — the Traditional-Chinese original is the authoritative version.
Lab 10 — how phase noise smears the carrier into an RF skirt
Breadcrumb: Simulation labs › Noise & jitter › This page (RF spectrum skirt). Upstream: white_noise_to_phase_noise; downstream: lab_08.
This lab connects the abstract phase-noise PSD to what you actually see on a spectrum analyzer: an ideal carrier is a single line in the spectrum; with phase noise, that line gets "smeared" into a continuous skirt (sidebands sloping down on both sides of the carrier). We synthesize directly in the time domain, take an FFT, and see it with our own eyes — this is exactly the picture in [P1] Fig. 8, and it's where the unit dBc/Hz (decibels relative to carrier per Hz) comes from.
Physical intuition (conclusion first): phase noise is not "an extra noise source sitting next to the carrier" — it is the carrier's own phase jittering. Stuff the jittering phase into the cosine's phase argument (phase modulation, PM), and the carrier's energy "leaks" from that one clean spectral line into nearby offset frequencies. How far it leaks and how much depends on the spectral shape of : phase noise → a skirt that falls off at dB/dec on either side of the carrier. Seeing the skirt means seeing "moved" next to the carrier.
1. Learning objectives
- Start from the time-domain PM signal and use an FFT to see the sideband skirt caused by phase noise.
- Compare an "ideal carrier (nearly a single spectral line)" against "with phase noise (continuous skirt)" to understand the physical meaning of dBc/Hz.
- Map phase noise (integrated white noise) to a dB/dec skirt slope on either side of the carrier.
- Recognize this plot as the time-domain version of [P1] Fig. 8.
2. Mathematical model
Carrier + excess phase. An oscillator output corrupted by phase noise is written as (a special case of canonical formula 1, with treated as constant):
is phase noise. White noise passed through a phase integrator (in the spirit of canonical formula 11: noise is first weighted by , then integrated by ) produces a random-walk-like phase:
- Why integrating white noise gives : an integrator in the frequency domain is , so power transfers as ; white noise ( flat) passing through this yields . This is exactly the signature skirt of a free-running oscillator (the spectral shape of canonical formula 21).
RF spectrum = power spectrum of the PM signal. Window (Hanning), take the FFT, take the magnitude squared, and normalize to the carrier peak:
- Sideband mechanism under the small-angle approximation (spec Section 10.2, ""): let ; at small angle
Each sideband's power relative to the carrier is ; summing over the continuous spectrum of produces the skirt.
- Dimension check: and are in rad (dimensionless), is dimensionless, and of that gives dBc ✓. The offset and share units (this lab uses normalized units).
3. Block diagram
4. Core Python code
Verbatim excerpt from main() in simulations/lab_10_rf_spectrum.py: cumsum white noise into
phase phi (scaled to ~0.03 rad rms to stay small-angle), then synthesize the clean carrier
and the noisy carrier, and finally apply a Hanning window, take the rFFT, normalize to the peak, and
convert to dB.
fs = 8192.0
n = 2 ** 18
t = np.arange(n) / fs
f0 = 512.0 # carrier (normalized units), 16 samples/cycle
# 1/f^2 phase noise: integrate white noise, scale to a visible (small) rms
white = RNG.standard_normal(n)
phi = np.cumsum(white) / fs
phi -= phi.mean()
phi *= 0.03 / np.std(phi) # ~0.03 rad rms -> small-angle regime
v_clean = np.cos(2 * np.pi * f0 * t)
v_noisy = np.cos(2 * np.pi * f0 * t + phi)
win = np.hanning(n)
def spec(x):
X = np.fft.rfft(x * win)
P = np.abs(X) ** 2
return P / P.max()
f = np.fft.rfftfreq(n, 1 / fs)
Pc = spec(v_clean)
Pn = spec(v_noisy)
off = f - f0 # offset from carrier
phi = np.cumsum(white) / fsis the discrete integrator (the source of ).phi *= 0.03 / np.std(phi)compresses the rms to ~0.03 rad, keeping it in the small-angle regime (so the skirt stays proportional to without spawning strong higher-order harmonic sidebands).P / P.max()normalizes power to the carrier peak, so the y-axis is naturally dBc.
5. Full script path
simulations/lab_10_rf_spectrum.py
(dependency: savefig from simulations/common/plot_utils.py. Everything else is numpy/matplotlib.)
Run with: python scripts/run_all_sims.py.
6. Parameter table
| Parameter | Variable | Value | Notes |
|---|---|---|---|
| Sample rate | fs | (normalized) | samples per second (dimensionless unit) |
| Number of samples | n | FFT length, sets frequency resolution | |
| Carrier frequency | f0 | (normalized) | 16 samples per cycle |
| Phase rms | — | rad | rms of after scaling (small angle) |
| Phase shape | — | (cumsum of white noise) | signature free-running skirt |
| Window function | win | Hanning | reduces FFT sidelobe leakage |
| Displayed offset | off | (normalized) | skirt range to the right of the carrier |
| Random seed | RNG | default_rng(10) | reproducible results |
Note: this lab deliberately uses normalized units (
fs,f0have no physical dimension); the focus is on shape (skirt slope and the single-line-vs-continuous-spectrum contrast), not absolute Hz.
7. Units table
| Quantity | Symbol | Unit | Value in this lab |
|---|---|---|---|
| Time | (normalized) s | ||
| Carrier frequency | (normalized) Hz | ||
| Excess phase | rad | rms | |
| Offset frequency | (normalized) Hz | ||
| Relative power | dBc | ||
| Phase PSD | rad²/Hz |
8. Simulation plot

9. How to read the plot
- Blue line (ideal carrier): energy is almost entirely concentrated at the carrier itself and drops off sharply as offset increases — the spectrum looks "almost like a single line". The small residual skirt comes from finite FFT length and window leakage, not physical phase noise.
- Red line (with phase noise): a continuous skirt appears on both sides of the carrier, sloping down with increasing offset. On a log-offset axis it is nearly a straight-line falloff, matching dB/dec for : this is the time-domain origin of the dBc/Hz curve.
- The single-line-vs-skirt contrast is the core message of this plot: the phase jitters → carrier energy leaks out → a spectral line becomes a skirt. "Lower and steeper skirt" means smaller phase noise.
- How to use it: the skirt height you measure on a spectrum analyzer (relative to the carrier, per Hz) is (dBc/Hz). Integrate it (see lab_08) to get rms jitter. This lab lets you "see" how that curve grows out of time-domain PM.
10. Corresponding paper equations/figures
- Core correspondence: [P1] A. Hajimiri and T. H. Lee, "A General Theory of Phase Noise in Electrical Oscillators," IEEE JSSC, 33(2), 1998, Fig. 8 — shows phase noise smearing the carrier into a sideband skirt. This lab is its time-domain synthesis version. [P1] Fig. 8 is on p.183 (checked against the original PDF).
- Carrier decomposition: canonical formula 1, (here is taken constant, ).
- Sideband mechanism (small-angle PM → ): spec Section 10.2, " (small-angle PM)".
- Origin of the skirt: phase integration of white noise, consistent with the spectral shape of canonical formula 21 ([P1] Eq.(21), p.185).
- Corresponds to site figure
rf_spectrum_phase_noise_sidebands.png; further reading: white_noise_to_phase_noise, psd_phase_noise_jitter.
11. Limitations and approximations
- This is a pedagogical toy model, not transistor-level: we directly "inject" a phase noise without actually simulating the full pipeline of transistor noise weighted by the ISF; the goal is to see "what the skirt looks like".
- Small-angle assumption: rms rad , so the skirt is proportional to with no strong higher-order sidebands. At large phase excursions, PM produces carrier compression and higher-order sidebands, which this plot does not cover.
- Normalized units:
fsandf0have no physical dimension, and the x-axis offset is also normalized; the focus is on shape and contrast, not absolute Hz. Matching a real 5 GHz, dBc/Hz result requires setting a real sample rate and an absolute level. - FFT artifacts: the blue line's residual skirt and the red line's far floor partly come from
finite-length FFT and Hanning window leakage, not entirely physical phase noise. Increasing
nor using a sharper window reduces this. - Single random realization: the plot comes from one trace with a fixed seed; a rigorous requires ensemble averaging (Welch) over many realizations, see lab_06.
Key takeaways
- Phase noise is not an extra source sitting beside the carrier — it is the carrier's own phase jittering → energy leaks from a single line into a sideband skirt.
- Taking the FFT of the time-domain lets you "see" the skirt of [P1] Fig. 8.
- phase noise (integrated white noise) → a dB/dec skirt on both sides of the carrier; skirt height is dBc/Hz.
- Under small-angle PM each sideband's relative power is , summing into a continuous spectrum ().
Further reading
- How the skirt grows out of white noise: white_noise_to_phase_noise
- dBc/Hz and jitter types: psd_phase_noise_jitter
- Integrating the skirt into jitter: lab_08_jitter_integration
- Building numerical intuition: numerical_feeling
- Applied to design/theory: how a lab measures this skirt (SA/delay-line/cross-correlation) → measurement_and_spurs