# Matlab Model Ams Systems

> Model a Phase-Locked Loop (PLL) IC from its datasheet or system specs using Mixed-Signal Blockset. Without this skill, agents universally select the wrong solver and produce non-functional PLL models — 100% of unguided attempts fail. Covers Integer-N, Fractional-N, Dual Modulus architectures, loop filter design, lock time optimization, VCO phase noise configuration, and msbPllArchitectures/msbPllFoundation block assembly. Use when: PLL modeling, frequency synthesizer design, phase noise simulation, lock time analysis, charge pump design, loop filter tuning, datasheet-to-model, Mixed-Signal Blockset PLL, msbPllArchitectures.

- Skill: `matlab/matlab-model-ams-systems` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add matlab/matlab-model-ams-systems`
- Raw SKILL.md: https://api.skillmd.com/api/skills/matlab/matlab-model-ams-systems/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: https://www.mathworks.com/content/dam/mathworks/license/pmrl/lic
- Author: matlab (https://skillmd.com/u/matlab)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/matlab/matlab-model-ams-systems

---


# Skill: PLL Datasheet Modeling -- Core (Phases 1-4)

Model a PLL IC from its datasheet or system specifications using Simulink
building blocks from the Mixed-Signal Blockset (MSB) foundation library
`msbPllFoundation`.

**Companion file**: `modeling-pll-datasheet-validate.md` covers Phases 5-9
(loop filter design, validation, measurement, iteration, pitfalls).

## When to Use

- Modeling a PLL IC from its datasheet (extracting parameters, selecting architecture)
- Designing a frequency synthesizer from system specs (fVco, fRef, lock time, phase noise targets)
- Building a behavioral PLL model in Simulink using Mixed-Signal Blockset
- Validating phase noise performance against datasheet measurements
- Selecting between Integer-N, Fractional-N, or Dual Modulus PLL architectures

## When NOT to Use

- Circuit-level PLL design (transistor-level VCO, charge pump schematic)
- PLL analysis without building a Simulink model (use `estimatePLLPhaseNoise` directly)
- Clock distribution or jitter cleaning (not frequency synthesis)
- Non-MSB PLL modeling (e.g., custom Simulink blocks without the Mixed-Signal Blockset)

---

## Workflow Directives (MANDATORY)

1. **Gather specs ONE AT A TIME (MANDATORY — no exceptions)** -- For ANY
   PLL or frequency synthesizer design request (spec-driven or exploratory),
   ask exactly ONE question per response. Do NOT list multiple questions or
   present a bulleted requirements checklist. This reduces cognitive load
   and makes the interaction conversational. Sequence:
   1. Output frequency (or frequency range)
   2. Reference frequency (flag if N > 200 — high in-band noise penalty)
   3. Architecture (Integer-N / Frac-N / auto — may be predetermined by N)
   4. Lock time target
   5. Phase noise / jitter / spur targets (or confirm "none")
   6. Charge pump current (offer typical value as default)
   7. VCO requirements (Kvco, phase noise profile — offer rule-of-thumb)
   8. Loop filter preference (order, BW override)
   9. Any other requirements?
   10. Save location (folder path for .slx and results)

   **Rules:**
   - Ask ONE question, wait for answer, then ask the next.
   - Skip questions already answered in the user's initial prompt.
   - Offer a sensible default in parentheses so user can just confirm.
   - After all specs are gathered, present the Design Plan (Directive 5, Step A).

2. **Iterate autonomously ONLY when targets are NOT met** -- If the first
   attempt PASSES with >3x margin, STOP. The BW formula already gives a
   good design — do NOT sweep BW or iterate "for completeness." Only
   sweep/iterate when the first attempt FAILS or margin is < 2x.
   When iteration IS needed, sweep parameters and re-simulate until met.

3. **Report progress and generate HTML summary** -- Print brief status per
   attempt (e.g., "BW=1MHz, PM=70 -> lock=5.2us X"). After ALL targets pass,
   generate an HTML report saved alongside the model. Required sections:

   **Report contents (mandatory):**
   - Summary box: pass/fail verdict with margin
   - Model screenshot: `print(['-s' model], path, '-dpng', '-r150')`
   - Architecture diagram (text-based)
   - Design parameters grid (fVCO, fRef, N, Icp, Kvco, filter type, etc.)
   - Loop filter component table with time constants (τ_z = R2·C2, τ_p3 = R3·C3)
   - **Transfer function box**: Z(s), G(s)=Icp·Kvco·2π·Z(s)/(N·s), H(s)=G/(1+G),
     plus key values: fc, PM, zero freq, pole freqs
   - **Bode plots** (open-loop + closed-loop): export from `pllOpenLoopPlot`/
     `pllCloseLoopPlot` via `exportgraphics(fig, path, 'Resolution', 150)`.
     Find figures by Tag: `'PllOpenLoopDynamicPlot'`, `'PllCloseLoopDynamicPlot'`
   - **Vctrl transient**: plot from simOut timeseries with lock time marker
   - Simulation results table (spec vs measured)
   - Simulation config (solver, stopTime, holdOff, averages)
   - **Session metrics**: include `[COST]` and `[DURATION]` placeholders in
     the report footer. The user fills these in from the Claude Code UI after
     the task completes (visible at session end).

   **How to export plots:**
   ```matlab
   pllOpenLoopPlot(Icp, Kvco, N, 0, R2, R3, 0, C1, C2, C3, 0);
   fig = findobj('Type','figure','Tag','PllOpenLoopDynamicPlot');
   exportgraphics(fig, fullfile(outDir,'open_loop_bode.png'), 'Resolution', 150);
   ```
   Use relative `src="filename.png"` paths in HTML. Open report with
   `web(reportPath, '-browser')`.

4. **Figures must be visible** -- After simulation, call
   `set(0,'DefaultFigureVisible','on')` and ensure all plot figures
   have `'Visible','on'`. Call `drawnow` to force rendering. The MCP
   MATLAB server defaults to `Visible='off'`.

5. **Show progress on screen at each step** -- At key milestones, print status:

   - **Step A — Design plan**: ASCII block diagram + params before building
     ```
     [PLL TB]──▶[PFD]──▶[CP]──▶[Loop Filter]──▶[VCO]──┐
        ▲                                               │
        └─────────────[Divider ÷N]◀─────────────────────┘
     ```
     Include: architecture, fRef, N, Icp, Kvco, Fc, PM, filter type, solver.
     When adding impairments, show updated diagram BEFORE implementing.
   - **Step B — Filter + Bode**: component values, then `pllOpenLoopPlot`/`pllCloseLoopPlot`
   - **Step C — Sim start**: `Simulating Pass 1 (lock time)... StopTime=9µs`
   - **Step D — Results**: `Lock time = 2.1 µs (target < 3 µs) ✓ [1.4× margin]`
   - **Step E — Pass 2** (only if PN spec): offsets, measured vs target, pass/fail

---

## Prerequisites

- Access to the target PLL IC datasheet (PDF) -- OR basic specs (fVco, fRef, lock time)
- Mixed-Signal Blockset installed (provides `msbPllFoundation` library)
- Control System Toolbox (for `estimatePLLPhaseNoise` validation, R2026b+)

## Entry Points

### A. Datasheet-Driven (Full workflow, Phases 1-4)
Use when you have a PLL IC datasheet. Follow all phases below.

### B. Spec-Driven (No datasheet)
Use when you have basic PLL specs but no datasheet. Follow Directive 1 to
gather specs, then derive remaining parameters.

**Parameter derivation rules:**
```
N = fVco / fRef  (or P*N+S for dual modulus)
BW = min(12/t_lock, fPFD/10)  (capped at fPFD/10 for stability)
Kvco: fVco/50 typical if not specified (e.g., 6 GHz → 120 MHz/V)
Icp: 1-5 mA typical (higher Icp → wider achievable BW with smaller R2)
PM: 50° default (60° if adding 4th-order pole)
```

**Architecture selection:**

| Condition | Architecture |
|-----------|-------------|
| N is integer, single prescaler | Integer N PLL with Single Modulus Prescaler |
| N is integer, need P/P+1 flexibility | Integer N PLL with Dual Modulus Prescaler |
| N is fractional, low spur requirement | Fractional N PLL with Delta Sigma Modulator |
| N is fractional, simple design | Fractional N PLL with Accumulator |

**DSM order selection** (when using Frac-N DSM):
- Order 1: simplest, highest spurs at fPFD/denom
- Order 2: good balance for most designs
- Order 3-4: lowest spurs, but more quantization noise energy pushed
  to high offsets (requires adequate filter attenuation)
- Match datasheet DSM order if available; default to order 3

**R-divider tradeoff** (when fRef ≠ fComp):
- Using R-counter: fComp = fRef/R → N_eff = fVco/fComp = N×R
- In-band noise penalty: +20×log10(N_eff) — larger N hurts in-band PN
- Only use R > 1 when channel spacing requires it (fComp = channel step)

**Spec-driven steps:**
1. Gather specs (Directive 1) → present Design Plan (Directive 5, Step A)
2. If VCO PN data available: validate VCO standalone first (see below)
3. Select architecture block from `msbPllArchitectures` (Strategy A — DEFAULT)
4. Design loop filter:
   - N ≤ 50: `CompSelectionMethod='Automatic'` with `Fc` and `Phi`
   - N > 50 (P79): `thirdOrderPassiveFilterDesign` → `CompSelectionMethod='Manual'`
   - N threshold applies to effective N (including fractional part)
5. Build model, simulate, present results

**VCO standalone validation** (when PN data provided):
```matlab
% 1. Create VCO testbench model
vcoModel = 'VCO_Validation';
new_system(vcoModel); open_system(vcoModel);
set_param(vcoModel, 'Solver', 'VariableStepDiscrete');
add_block('msbPllFoundation/Ring Oscillator VCO', [vcoModel '/VCO']);
add_block('msbPllMeasurements/VCO Testbench', [vcoModel '/VCO TB']);
add_line(vcoModel, 'VCO TB/1', 'VCO/1', 'autorouting', 'smart');
add_line(vcoModel, 'VCO/1', 'VCO TB/1', 'autorouting', 'smart');

% 2. Get PeriodJitter and CornerFrequency from PN data
[pJitter, cFreq] = msblks.VCO.estimatePhaseNoiseCore(fVco, Foffset, PN_dBc);
set_param([vcoModel '/VCO'], 'Fo', num2str(fVco), ...
    'PeriodJitter', num2str(pJitter), 'CornerFrequency', num2str(cFreq));

% 3. Simulate and compare to datasheet (accept ±3 dB)
sim(vcoModel);
ud = get_param([vcoModel '/VCO TB'], 'UserData');
```

Skip to Phase 4.0 (Strategy A assembly) after deriving parameters.

### C. Tune Existing Model (Meet a new spec)
Use when the user provides an existing `.slx` model and wants to meet a target
(lock time, phase noise, spurs) without rebuilding from scratch.

**Workflow:**
1. **Probe** — extract current params: `Fc`, `Phi`, `N`, `OutputCurrent`, `Kvco`,
   `CompSelectionMethod`, filter components via `get_param`
2. **Check for PLL Testbench** — if missing or PLL input unconnected, ASK the
   user for fComp (P104). Add a PLL Testbench if needed.
3. **Baseline sim** — `sim(model)`, read `get_param(tbBlk, 'UserData')` for
   lock time, frequency, phase noise. This is the ONLY valid baseline (P103).
4. **Identify the lever:**
   - Lock time too slow → increase `Fc` (BW ≈ 12/t_lock)
   - Phase noise too high in-band → decrease `Fc`, increase Icp, or reduce N
   - Spurs too high → increase filter order or narrow `Fc`
5. **Redesign** — set new `Fc` (and `Phi` if needed), keep
   `CompSelectionMethod='Automatic'` so the block recomputes filter components
6. **Re-simulate** — read testbench UserData. Iterate until spec is met.
7. **Report** — before/after comparison with trade-off notes

**Key rules:**
- NEVER estimate lock time from Vctrl settling (P103)
- NEVER guess fComp from `Fo/N` or `RefFreq` param (P104)
- Cap `Fc` at `fPFD/10` for stability
- Use `lock_time ≈ 12/Fc` only for initial sizing, then verify with testbench

---

## Availability Check (MANDATORY)

Before using ANY function or block, verify it exists. Check `exist(func,'file')`
for key functions (`thirdOrderPassiveFilterDesign`, `estimatePLLPhaseNoise`,
`phaseNoiseMeasure`, `phaseNoiseToJitter`) and `exist(lib,'file')==4` for
libraries (`msbPllFoundation`, `msbPllMeasurements`, `msbPllArchitectures`).
If not found, do NOT use — skip dependent steps.

---

## Phase 1: Extract Datasheet Parameters

### 1.0 Reading the Datasheet PDF

Use MATLAB's `extractFileText` (never read PDFs directly with the Read tool):

```matlab
pdfPath = 'path/to/datasheet.pdf';
txtContent = extractFileText(pdfPath);
txtPath = strrep(pdfPath, '.pdf', '_extracted.txt');
fid = fopen(txtPath, 'w'); fprintf(fid, '%s', txtContent); fclose(fid);
fprintf('Extracted %d characters to: %s\n', strlength(txtContent), txtPath);
```

### 1.1 Architecture Identification

Determine the PLL topology from the functional block diagram:

| Question | Typical Options |
|----------|----------------|
| Integer-N or Fractional-N? | Integer-only, Fractional with accumulator, Fractional with DSM |
| DSM order (if fractional)? | 1st, 2nd, 3rd, 4th |
| Prescaler type? | Single modulus, Dual modulus (P/P+1) |
| Integrated VCO? | Yes / No (external) |
| Reference path? | Direct, with R counter, with doubler, with divider |
| Output dividers? | None, programmable divide chain |
| Feedback tap point? | Before output divider (VCO), after output divider |

### 1.2-1.4 Detailed Parameter Extraction

See **references/datasheet-extraction.md** for the full parameter tables:
- 1.2: Core PLL parameters (PFD, CP, dividers, VCO, output stage)
- 1.3: Noise parameters (VCO PN, PNSYNTH, flicker, jitter, spurs)
- 1.4: Frequency plan worked example

---

## Phase 2: Select Assembly Strategy

### Decision Tree (ALWAYS follow this)

```
START
  │
  ├─ Does the PLL topology match an msbPllArchitectures template?
  │   ├─ YES ──► Strategy A (Architecture block) ◄── DEFAULT
  │   └─ NO ───► Strategy B (Foundation blocks)
  │
  └─ Do you need EXTERNAL custom noise injection (BLWN, spur sources wired
     into the signal path OUTSIDE the PLL subsystem)?
      ├─ NO ───► Strategy A (Architecture block) ◄── DEFAULT
      └─ YES ──► Strategy A + editSystem (flatten, then inject)
                 OR Strategy B (if injection point is before CP or after VCO)
```

**Strategy A is the default for ALL designs** — spec-driven or datasheet-driven.
Foundation blocks (Strategy B) are only needed when topology has no matching
architecture template (e.g., dual-loop, injection-locked, external VCO with
non-standard feedback).

| Strategy | When to Use | Performance | Complexity |
|----------|-------------|-------------|------------|
| **A: Architecture block** | **Default.** Any standard Int-N, Frac-N, Dual-Modulus PLL | **3.3x faster sim** (65s vs 212s for 5 GHz PLL) | 4 blocks, 4 connections |
| **A + editSystem** | Need to inject CP broadband noise or add custom impairments | Same speed until flattened | Flatten adds ~5 internal blocks |
| **B: Foundation blocks** | Non-standard topology, external VCO, dual-loop, or educational/visualization purposes | Baseline (slowest) | 9+ blocks, 11+ connections |

### Probe-First Pattern (MANDATORY before `set_param`)

Before setting ANY block parameter, probe the mask to discover exact parameter
names. Never guess parameter names from documentation or memory.
See `references/probing-simulink-models.md` for the full probe workflow.

```matlab
blk = [model '/PLL'];
m = Simulink.Mask.get(blk);
paramNames = {m.Parameters.Name};
fprintf('Available params (%d):\n', numel(paramNames));
cellfun(@(p) fprintf('  %s\n', p), paramNames);
```

This eliminates errors like using `'Icp'` (wrong) instead of `'OutputCurrent'`
(correct), or `'DividerRatio'` (wrong) instead of `'N'` (correct).

### 2.1 `msbPllArchitectures` -- Pre-built PLL Templates (Strategy A)

| Architecture Block | Topology | Divider Params |
|--------------------|----------|----------------|
| Integer N PLL with Single Modulus Prescaler | PFD->CP->LF->VCO->Single Prescaler | `Nmin`, `N` (integer) — set N FIRST |
| Integer N PLL with Dual Modulus Prescaler | PFD->CP->LF->VCO->Dual Prescaler | `ProgramCounter`(P), `PrescalerDivider`(N), `SwallowCounter`(S) — constraints: P > S > 0 (P105) |
| Fractional N PLL with Accumulator | PFD->CP->LF->VCO->Frac Divider (Accum) | `N` (fractional), `Nmin` |
| Fractional N PLL with Delta Sigma Modulator | PFD->CP->LF->VCO->Frac Divider (DSM) | `N` (fractional), `Nmin`, `dsm` (order) |

**Key promoted parameters** (common to all):

| Category | Parameters |
|----------|-----------|
| VCO | `Kvco`, `Fo`, `Amplitude`, `AddPhaseNoise`, `Foffset`, `PhaseNoise`, `PeriodJitter`, `CornerFrequency`, `FlickerExponent` |
| Charge Pump | `OutputCurrent`, `EnableCurrentImpairments`, `CurrentImbalance`, `LeakageCurrent`, `EnableTimingImpairments` |
| Loop Filter | `CompSelectionMethod`(`Automatic`/`Manual`), `Fc`, `Phi`, `FilterType`, `C1`-`C4`, `R2`-`R4`, `LfEnableImpairments`, `Temperature` |
| PFD | `DeadbandCompensation`, `EnableImpairments` |
| Analysis | `ol_opt`, `cl_opt`, `estimatePn` |
| Probe | `pfd_up_dn`, `cp_out`, `lf_out`, `ps_out` |

**Built-in callbacks**:
- `msblks.PLL.editSystem(gcb)` -- flatten to editable subsystem
- `msblks.PLL.estimatePhaseNoise(gcb)` -- analytical PN estimation
- `msblks.VCO.plotMaskFigure(gcb)` -- plot PN fit vs data

### 2.2 `msbPllFoundation` -- Individual Building Blocks (Strategy B)

See **references/assembly-code.md** for the full block table and parameters.
Key blocks: PFD, Charge Pump, Loop Filter, Ring Oscillator VCO, Fractional Clock Divider with DSM.

### 2.3 Gap Analysis

Architecture blocks cover PFD, CP, LF, VCO, and Dividers. For R counter,
ref doubler, RF output divider, or CP broadband noise: flatten with
`editSystem`, then add custom blocks inside the subsystem.

---

## Phase 3: Create Custom Blocks / Customize Architecture

### 3.0 Flattening (`msblks.PLL.editSystem`)

Set all mask parameters FIRST, THEN flatten. After flattening, the subsystem
contains individual blocks (PFD, CP, LF, VCO, Divider) that you can modify.

```matlab
blk = [model '/PLL'];
set_param(blk, 'Kvco','40e6', 'Fo','4.225e9', 'OutputCurrent','5e-3', ...
    'N','422.52', 'CompSelectionMethod','Automatic', 'Fc','60e3', 'Phi','48');
msblks.PLL.editSystem(blk);  % Flatten AFTER setting params
```

### 3.1-3.4 Custom Block Recipes

See **references/assembly-code.md** for: CP broadband noise (3.1), reference
path (3.2), RF output divider (3.3), feedback select mux (3.4).

---

## Phase 4: Assemble the Model

> **PERFORMANCE DIRECTIVE — Batch Model Assembly**
> Execute the ENTIRE model assembly in ONE `mcp__matlab__evaluate_matlab_code` call
> (new_system, set_param, add_block, add_line, scope setup — ALL in one script).
> Each MCP round-trip = ~10-15s overhead. Batched = ~30s vs individual = 5+ min.
> Pattern: (1) compute params, (2) write assembly script to .m file in save folder,
> (3) execute via `mcp__matlab__run_matlab_file` (keeps terminal clean — no code dump),
> (4) verify. Using `run_matlab_file` instead of `evaluate_matlab_code` for large
> scripts prevents raw code from cluttering the user's screen during live demos.

### 4.0 Strategy A: Architecture Block Assembly (DEFAULT)

Architecture blocks: 3.3x faster sim, 56% fewer blocks, 64% fewer connections.
Full assembly code template in **references/assembly-code.md**. Key sequence:

1. `new_system` + solver config (`VariableStepDiscrete`, `ReturnWorkspaceOutputs='on'`)
2. `add_block` from `msbPllArchitectures/<type>`
3. Set divider: `Nmin='1'` first, then `N`, then `Nmin` to final value (P57/P92)
4. Set VCO params: `Kvco`, `Fo`, `OutputCurrent`, `AddPhaseNoise`, `RefFreq`
5. Loop filter: `thirdOrderPassiveFilterDesign` for N>50 (P79), else `Automatic`
6. PFD timing: `PropDelay = max(50e-12, min(5e-12, 1/(2*fVCO)/10))`, `MaxFreqInterest = 2*fVCO` (50ps floor — block rejects smaller values)
7. Enable `lf_out='on'` for Vctrl probe
8. Add PLL Testbench (`Fo=fPFD`, `ExpectedFreq=fVCO`, `SampleRate=8*fVCO`)
9. Set `SpectralAverages='2'` (P102: mask default is 4), `LockTimeOption='on'`, `PhaseNoiseOption='off'` (P83)
10. `StopTime = min(3*t_lock, 50e-6)`, `HoldOffTime = min(1.5*estLock, 0.8*StopTime)`
11. Set paired vectors via `Simulink.Mask.get`: `PhaseNoiseFreqOffset`, `TargetPhaseNoiseVector` (P71, P100: use `-999` if no targets — mask rejects `-inf`)
12. Connect: TB/1→PLL/1, PLL/1→TB/1, PLL/2→Scope+ToWorkspace
13. `Simulink.BlockDiagram.arrangeSystem(model); drawnow; set_param(model,'ZoomFactor','FitSystem'); drawnow;` (P95)

### 4.1 Strategy B: Foundation Blocks

Use ONLY for non-standard topologies. See **references/assembly-code.md**.

### 4.2 Stability Analysis (ALWAYS before time-domain sim)

Confirm PM > 45° and no closed-loop peaking > 1 dB before running full sim.
- `pllOpenLoopPlot(Icp,Kvco,N,Fc,R2,R3,R4,C1,C2,C3,C4)` / `pllCloseLoopPlot(...)`
- For 3rd-order passive: R4=0, C4=0. See **references/stability-analysis.md**.
- **If `pllOpenLoopPlot` crashes** (ylim error at phase <= -180°): use manual Bode
  fallback per P106 — compute Z(s), G(s) via `logspace` sweep. Do NOT use
  Control System Toolbox (`tf`, `bode`) — it is not required.

### 4.3 Simulate and Read Results

```matlab
simOut = sim(model);
delete(findall(0,'Type','figure','Tag','Msgbox_Warning'));
% Read lock time from PLL Testbench model workspace
sid = Simulink.ID.getSID([model '/PLL Testbench']);
sidParts = split(sid, ':'); sidSuffix = sidParts{2};
mdlWs = get_param(model, 'ModelWorkspace');
lockTime = evalin(mdlWs, ['LockTime_' sidSuffix]);
freq = evalin(mdlWs, ['Frequency_' sidSuffix]);

% Alternative: read from UserData (works after sim completes)
ud = get_param([model '/PLL Testbench'], 'UserData');
lockTime = ud.lockTime;  % seconds
freq = ud.freq;          % Hz
pnLevels = ud.phaseNoiseLevel; % dBc/Hz vector
```

**P103: NEVER estimate lock time from Vctrl settling.** The PLL Testbench uses
frequency-error-based detection (`FreqErrorTol`) — this is the ONLY valid lock
time measurement. Manual Vctrl analysis gives incorrect results.

**P104: If the model has NO PLL Testbench or unconnected reference input, you
CANNOT determine fComp.** The `RefFreq` parameter is for PN estimation only —
it does NOT define the actual reference clock. ASK the user for fComp before
proceeding. Do not guess or calculate it from `Fo/N`.

Probe tab ports (after VCO out port 1): pfd_up, pfd_dn, cp_out, lf_out, ps_out.
`HoldOffTime` must be < `StopTime`, otherwise no measurements.

---

## Quick Reference

```
f_PFD = f_REFIN*(1+D)/(R*(1+T))  |  f_VCO = f_PFD*(INT+FRAC/MOD)  |  f_OUT = f_VCO/RF_DIV
N_eff = INT+FRAC/MOD (from VCO)  |  N_eff = (INT+FRAC/MOD)*RF_DIV (from divider output)
In-band PN  = PNSYNTH + 10*log10(f_PFD) + 20*log10(N)
1/f PN at f = PN1_f + 10*log10(10kHz/f) + 20*log10(f_RF/1GHz)
Divider effect = -20*log10(RF_DIV) on output phase noise
```

## Happy Path Cheat Sheet (Spec → Lock Time Verified)

Most common workflow in ~20 steps:

```
1. User gives: fVCO, fRef, lock time target
2. Derive: N = fVCO/fRef, Fc = 12/t_lock (cap at fPFD/10), Kvco = fVCO/50
3. Present Design Plan (block diagram + params)
4. Build model (ONE mcp call):
   - new_system, VariableStepDiscrete solver
   - add_block msbPllArchitectures/Integer N PLL...
   - set Nmin='1', N, Nmin=N
   - set Kvco, Fo, OutputCurrent, Fc, Phi='50'
   - add PLL Testbench (Fo=fRef, ExpectedFreq=fVCO, SampleRate=8*fVCO)
   - set LockTimeOption='on', SpectralAverages='2'
   - connect TB↔PLL, enable lf_out, add scope
   - StopTime = min(3*12/Fc, 50e-6), HoldOff = 1.5*12/Fc
   - arrangeSystem + FitSystem
5. Plot Bode: pllOpenLoopPlot(...), confirm PM > 45° (if ylim crash, use manual fallback P106)
6. sim(model)
7. ud = get_param(tbBlk, 'UserData'); lockTime = ud.lockTime;
8. Report: lock_time vs target, margin, PASS/FAIL
9. If margin > 3x → DONE. If not → increase Fc by 50%, repeat from step 5.
```

**Library names (canonical):** `msbPllArchitectures`, `msbPllFoundation`,
`msbPllMeasurements`, `msbUtilities`

---

Copyright 2026 The MathWorks, Inc.

