Generated banner for Matlab Model Ams Systems
Generated logo for Matlab Model Ams Systems

Matlab Model Ams Systems

MathWorksOfficialCreated by MathWorks

  • Skill
  • Workflow
  • Software development
  • BSD-2-Clause
  • No issues found

From the author

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.
— the description by MathWorks

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured, automated workflow for modeling Phase-Locked Loop (PLL) integrated circuits in Simulink. It leverages the Mixed-Signal Blockset to ensure accurate simulation of frequency synthesizers, including Integer-N, Fractional-N, and Dual Modulus architectures. The skill guides the user through parameter extraction from datasheets, architecture selection, loop filter design, and performance validation, preventing common simulation failures caused by incorrect solver or block configuration.

What it does

  • Extracts technical parameters from PLL IC datasheets
  • Automates the assembly of behavioral PLL models using Mixed-Signal Blockset
  • Calculates loop filter components for stability and lock time targets
  • Validates VCO phase noise performance against datasheet specifications
  • Generates HTML reports with Bode plots, transient analysis, and design parameters
  • Provides a standardized iterative workflow for meeting performance targets

When to use it

  • Modeling a PLL IC from a datasheet
  • Designing a frequency synthesizer from system specifications
  • Performing lock time analysis or phase noise simulation
  • Tuning an existing PLL model to meet new performance requirements

Advantages

  • Prevents common modeling failures by enforcing correct solver and block usage
  • Accelerates simulation setup through batch assembly scripts
  • Ensures design stability via automated Bode plot analysis
  • Provides a consistent, repeatable methodology for datasheet-to-model conversion

Usage examples

“Model a 5GHz Integer-N PLL from this datasheet.”
The agent extracts parameters, selects the Integer-N architecture block, designs the loop filter, and generates a simulation report.
“My PLL lock time is too slow, how do I fix it?”
The agent probes the current model, identifies the loop bandwidth as the lever, adjusts the filter parameters, and re-simulates to verify the new lock time.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/matlab/matlab-model-ams-systems/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip matlab-model-ams-systems.zip -d .agents/skills

Documentation by MathWorks

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:

    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:

ConditionArchitecture
N is integer, single prescalerInteger N PLL with Single Modulus Prescaler
N is integer, need P/P+1 flexibilityInteger N PLL with Dual Modulus Prescaler
N is fractional, low spur requirementFractional N PLL with Delta Sigma Modulator
N is fractional, simple designFractional 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):

% 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):

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:

QuestionTypical 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).

StrategyWhen to UsePerformanceComplexity
A: Architecture blockDefault. Any standard Int-N, Frac-N, Dual-Modulus PLL3.3x faster sim (65s vs 212s for 5 GHz PLL)4 blocks, 4 connections
A + editSystemNeed to inject CP broadband noise or add custom impairmentsSame speed until flattenedFlatten adds ~5 internal blocks
B: Foundation blocksNon-standard topology, external VCO, dual-loop, or educational/visualization purposesBaseline (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.

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 BlockTopologyDivider Params
Integer N PLL with Single Modulus PrescalerPFD->CP->LF->VCO->Single PrescalerNmin, N (integer) — set N FIRST
Integer N PLL with Dual Modulus PrescalerPFD->CP->LF->VCO->Dual PrescalerProgramCounter(P), PrescalerDivider(N), SwallowCounter(S) — constraints: P > S > 0 (P105)
Fractional N PLL with AccumulatorPFD->CP->LF->VCO->Frac Divider (Accum)N (fractional), Nmin
Fractional N PLL with Delta Sigma ModulatorPFD->CP->LF->VCO->Frac Divider (DSM)N (fractional), Nmin, dsm (order)

Key promoted parameters (common to all):

CategoryParameters
VCOKvco, Fo, Amplitude, AddPhaseNoise, Foffset, PhaseNoise, PeriodJitter, CornerFrequency, FlickerExponent
Charge PumpOutputCurrent, EnableCurrentImpairments, CurrentImbalance, LeakageCurrent, EnableTimingImpairments
Loop FilterCompSelectionMethod(Automatic/Manual), Fc, Phi, FilterType, C1-C4, R2-R4, LfEnableImpairments, Temperature
PFDDeadbandCompensation, EnableImpairments
Analysisol_opt, cl_opt, estimatePn
Probepfd_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.

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
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.

Files

references/pitfalls.md

PLL Modeling Pitfalls and Lessons Learned

Reference file for modeling-pll-datasheet-validate.md. Organized by category.


Solver & Wiring (P1-P3)

  • P1: Always use VariableStepDiscrete solver

  • P2: Use Simulink.Mask.get for paired vector parameters

  • P3: Use add_line with {'autorouting','smart'} (NOT 'autoroute','on')

Testbench Configuration (P4-P10)

  • P4: VCO Testbench provides the control voltage

  • P5: msblks.utilities.setStopTime is a mask callback -- compute manually: msblks.utilities.acStopTime(avg, RBW, holdoff)

  • P6: Always use Ring Oscillator VCO (not plain VCO)

  • P7: Must call msblks.VCO.estimatePhaseNoiseCore(f0, Foffset, PN) to get periodJitter & cornerFreq

  • P8: Enable "Plot and log measurements" on testbench blocks

  • P9: RBW = half the lowest offset; set via Simulink.Mask.get

  • P10: PLL TB: output=ref clock, input=VCO output

Analysis & Measurement (P11-P17)

  • P11: estimatePLLPhaseNoise returns dense grid (~500pts) -- use interp1(log10(...)) for specific offsets

  • P12: Must pass ChargePumpNoiseDensity and ChargePumpFlickerCorner to estimatePLLPhaseNoise

  • P13: Avoid phase noise offsets below 100 kHz for PLL sims (sim time explodes)

  • P14: Model layout: forward path horizontal, feedback mirrored below

  • P15: Enable Loop Filter thermal noise (LfEnableImpairments='on')

  • P16: Model CP broadband noise with external Band-Limited White Noise

  • P17: PLL Testbench targets must come from datasheet, not analytical prediction

Impairments (P21-P28)

  • P21: CP current mismatch ON, CP timing OFF (too aggressive), LF thermal ON, PFD edge OFF

  • P22: Dual Modulus Prescaler params: P, N, S

  • P23: Loop Filter Temperature must match datasheet test conditions

  • P24: Fractional Clock Divider with Accumulator has 3 output ports

  • P25: ReturnWorkspaceOutputs needed for simOut access

  • P26: Prefer msbPllArchitectures blocks over manual wiring

  • P27: Baseband PLL for fast behavioral analysis

  • P28: Clock Jitter Measurement outputs MUST be connected (Display blocks)

Architecture Block Internals (P29-P39)

  • P29: VCO Testbench has NO Fo/Kvco. Always probe with Simulink.Mask.get

  • P30: Ring Oscillator VCO output is digital 0/1

  • P31: To Workspace -> simOut.<var>; Testbench logged data -> base workspace

  • P32: Testbench logged struct: simStopTime, zcData, PnFOffset, Pn, phaseNoiseFreq, phaseNoiseLevel, CenterFreq, Avg

  • P33: Prefer Triggered Subsystem for zero-crossing capture

  • P34: editSystem breaks link, resolves N, removes mask. Set params BEFORE calling it

  • P35: After editSystem: PFD, CP, LF, VCO, divider, Constant(N), terminators

  • P36: Do NOT manually break link + remove mask -- use editSystem

  • P37: Mask callbacks (plotButtonLoopDynamics, estimatePhaseNoise) only work before editSystem

  • P38: Flattening is safe at any VCO frequency if PFD timing is scaled (P39)

  • P39: PFD PropDelay = max(50e-12, min(5e-12, 1/(2*fVco)/10)), MaxFreqInterest = 2*fVco (50ps floor — block rejects smaller)

Design Rules (P40-P49)

  • P40: Cap loop BW at 500 kHz: Fc = min(fPfd/20, 500e3)

  • P41: DSM quantization noise dominates in-band -- validate only at offsets >10x loop BW

  • P42: phaseNoiseToJitter API: [~,~,Jrms_s] = phaseNoiseToJitter(PNFreq, PNPow, 'Frequency', fCarrier)

  • P43: PLL TB: Fo=fComp (the PFD comparison frequency, NOT fVco and NOT fRef if R>1), ExpectedFreq=fVco, SampleRate=8*fVco. When an R-divider is used (fComp = fRef/R), Fo must equal fComp since that is the actual reference frequency seen by the PFD.

  • P44: phaseNoiseFreq/phaseNoiseLevel = user offsets; PnFOffset/Pn = full 301-pt FFT

  • P45: HoldOffTime must be slightly above the estimated lock time (e.g., 1.2-1.5x the estimated lock time). Do NOT use 5x the target lock time — that wastes simulation time. Example: if estimated lock = 0.4ms, use HoldOffTime = 0.5ms. The block mask shows a "Recommended min. simulation stop time" — always set StopTime to match or exceed that value.

  • P46: PFD impairments cannot be enabled for VCO > ~4 GHz

  • P47: msblks.VCO.estimatePhaseNoiseCore signature: (f0, f, LofF)

  • P48: getPllLoopResponse returns forward-path gain (no /N). True OL = Gofs/N

  • P49: isempty(struct) is false even for empty structs -- use isempty(fieldnames(s))

Library & API (P50-P57)

  • P50: MSB library names: msbPllArchitectures, msbPllFoundation, msbPllMeasurements, msbUtilities (NOT msblks)

  • P51: pllOpenLoopPlot(Icp, Kvco_Hz, N, Fc, R2, R3, R4, C1, C2, C3, C4) -- unused components = 0

  • P52: PLL TB has 1 outport (ref clock) and 1 inport (signal to measure)

  • P53: PLL TB results are in model workspace: Frequency_<SID>, LockTime_<SID>

  • P54: HoldOffTime must be > estimated lock time AND < StopTime. Use 1.2-1.5x the estimated lock time (NOT 5x the target), capped at 0.8×StopTime (P87). Always set StopTime to match the "Recommended min. simulation stop time" shown in the testbench block mask.

  • P55: Nonlinear lock time is 2-4x linear. Initial BW estimate: Fc = 12 / t_lock_target (combines 4/t_lock with 3x nonlinear factor). This gives a first attempt close to the final answer, minimizing design iterations. Example: 5 µs target → start at Fc = 2.4 MHz, not 500 kHz.

  • P56: Prefer CompSelectionMethod='Automatic' over manual filter design

  • P57/P92: set_param order: set Nmin='1' FIRST (to lower the floor), then N, then Nmin to final value. The old advice "set N before Nmin" fails when the mask's default Nmin > the new N (e.g., default Nmin=100, new N=65). Sequence: set_param(blk,'Nmin','1'); set_param(blk,'N',num2str(N)); set_param(blk,'Nmin',num2str(Nmin));

Simulation Workflow (P58-P99)

  • P58: fourthOrderPassiveFilterDesign fails at wide BW -- use 3rd-order + manual 4th pole

  • P59: Dual Modulus: set Nmin low BEFORE prescaler values, then raise Nmin

  • P60: set_param for StopTime doesn't take effect during active sim -- stop first

  • P61: Default SpectralAverages to 2 unless user asks for more

  • P62: Resize PLL TB block for readability: ~350x300 pixels

  • P63: Integer-N PLLs do NOT have DSM -- don't reference DSM noise

  • P64: In-band PN is meaningless without impairments enabled

  • P65: "Apply or cancel unapplied changes" error -- ask user to close open dialogs

  • P66: Dual-Modulus prescaler produces sub-harmonic spurs at fRef*k/N

  • P67: For spur analysis, set last offset to 1.2xfRef (not exactly fRef)

  • P68: MCP preserves only one figure -- use tiledlayout(1,2) for all results in one figure

  • P69: Do NOT use msbUtilities/Clock Generator as the reference source in PLL models. ALWAYS use msbPllMeasurements/PLL Testbench — it provides both the reference clock (outport) AND phase noise/lock time measurement (inport). Clock Generator is only for standalone VCO testing.

  • P70: PLL Testbench measurement options (Setup tab checkboxes) are OFF by default. You MUST explicitly enable them with the correct mask parameter names: set_param(tb, 'LockTimeOption', 'on', 'PhaseNoiseOption', 'on'). The frequency measurement is FrequencyMeasureOption (on by default). Without enabling these, no lock time or phase noise is measured. PlotAndLogPhaseNoise alone is NOT sufficient — it only controls logging/plotting after measurement is enabled.

  • P71: PLL Testbench PhaseNoiseFreqOffset and TargetPhaseNoiseVector are PAIRED vectors — they MUST have the same length or the InitFcn callback will error on simulation. When setting custom measurement offsets, ALWAYS set BOTH vectors together via Simulink.Mask.get(tb). The default TargetPhaseNoiseVector has 4 elements; if you change PhaseNoiseFreqOffset to a different length (e.g., 6 offsets), you MUST update TargetPhaseNoiseVector to match. Set these BEFORE enabling PhaseNoiseOption.

  • P72: Do NOT use a 2nd-order approximation (H(s) = (2*zeta*wn*s + wn^2) / (s^2 + ...)) for phase noise prediction. Use the ACTUAL 3rd-order filter impedance from thirdOrderPassiveFilterDesign output (C1, C2, C3, R2, R3) to compute the real open-loop gain. The 2nd-order approximation can be 3-5 dB off at offsets near the loop bandwidth.

  • P73: When phase noise targets are specified, the iteration in Phase 9 is MANDATORY — do not proceed with a design that fails analytical PN checks. The primary knobs are: (1) increase fRef to decrease N (most effective for in-band), (2) narrow BW (for out-of-band VCO noise), (3) increase Icp. Always verify lock time still meets target after BW changes.

  • P74: VCO phase noise offset vector must ONLY contain values explicitly specified in the datasheet. Do NOT extrapolate or add additional offset points (e.g., 1kHz, 10kHz) that are not in the datasheet table. Using extrapolated values gives a false sense of accuracy. If the datasheet specifies PN at [100kHz, 1MHz, 3MHz, 10MHz], use exactly those 4 points.

  • P75: PLL Testbench StopTime must always match or exceed the "Recommended min. simulation stop time" displayed in the testbench block mask. This value is computed from: HoldOffTime + SpectralAverages / ResBandwidth + margin. Never use an arbitrary short StopTime (like 10μs) when the testbench needs milliseconds for PN measurement. If full sim is impractical, note the limitation explicitly.

  • P76: NEVER delete a block or line without reconnecting all affected ports. When replacing a Scope with a To Workspace (or vice versa), add the new block and connect it BEFORE deleting the old one — or use a branch so both stay connected. After ANY block deletion or line modification, run the dangling line check:

lines = find_system(model, 'FindAll', 'on', 'Type', 'line');
for i = 1:numel(lines)
    src = get_param(lines(i), 'SrcPortHandle');
    dst = get_param(lines(i), 'DstPortHandle');
    if any(src == -1) || any(dst == -1)
        warning('Dangling line found — delete or reconnect it');
        delete_line(lines(i));
        break;
    end
end
  • P77: When ReturnWorkspaceOutputs='on' is set on the model, To Workspace block data is accessed via simOut.<VariableName> (e.g., simOut.Vctrl), NOT from the base workspace. The result is a timeseries object — access time with .Time and values with .Data. Testbench logged data (e.g., pll_phase_noise_out) still goes to the base workspace via evalin('base', ...).

  • P78: getPllLoopResponse may report different crossover/PM values than the MSB architecture block's internal auto-design. This is a known gain normalization difference (P48). When the PLL locks correctly in simulation, trust the time-domain result as ground truth. Present design target values (fc, PM) alongside analytical plots and note any discrepancy in the report.

  • P79: CompSelectionMethod='Automatic' fails silently for high-N PLLs (N > ~50). The architecture block's auto-design places the forward-path gain crossover at Fc without dividing by N. For N=288.6, requesting Fc=2 MHz gives a true loop BW of only 47 kHz with PM=5° (borderline unstable). The fix: use thirdOrderPassiveFilterDesign(Fc, PM, Icp, Kvco, N) which correctly includes N in the loop gain calculation, then set CompSelectionMethod='Manual' with the computed values. Rule of thumb: always use manual filter design when N > 50.

  • P80: Use scientific notation strings for high-frequency parameters. For frequencies > 1 GHz, prefer set_param(blk, 'Fo', '20e9') over set_param(blk, 'Fo', num2str(fVco)). Scientific notation is easier to verify at a glance ('20e9' vs '20000000000'), less prone to variable-copy errors, and matches how the mask displays values. When computing from variables, use sprintf('%g', val) for compact scientific form.

  • P81: PFD block has 2 output ports (UP and DOWN) — both must connect to Charge Pump. When building from foundation blocks (not architecture block), the PFD output port 1 = UP pulse, port 2 = DOWN pulse. The Charge Pump has 2 input ports (UP, DOWN). Connecting only the UP port causes runaway positive feedback (Vctrl ramps unbounded). The architecture block handles this internally, but if you flatten or build from foundation blocks, verify both PFD→CP connections exist.

  • P82: Ultra-low jitter targets (< 50 fs) require narrower BW than the lock-time formula suggests. The 12/t_lock formula (P55) optimizes for lock time. For parts like ADF4382 (20 fs target) or ADF4368 (29 fs target), start with BW = 500 kHz–1 MHz and verify jitter analytically (Section 5.6) before widening for lock time. A BW of 4 MHz at 20 GHz gives ~34 fs — failing a 25 fs target even though lock time passes easily.

  • P83: Phase noise measurement OFF by default in PLL Testbench. PN measurement adds 2-5 minutes of sim time (requires long holdoff + spectral averaging). Set PhaseNoiseOption='off' and PlotAndLogPhaseNoise='off' during initial model build. Enable ONLY when user explicitly requests PN results. For demos/quick validation, measure lock time only — it completes in seconds.

  • P84: Set TargetLockTime on PLL Testbench to the actual user spec. Default is too low (3 µs), causing misleading "Target" display. Use mask.getParameter('TargetLockTime').Value = num2str(t_lock).

  • P85/P95: Model must fill the canvas without manual zoom. After assembly, call Simulink.BlockDiagram.arrangeSystem(model) to auto-layout blocks optimally, then drawnow; set_param(model, 'ZoomFactor', 'FitSystem'); drawnow; to zoom the canvas to fit the arranged blocks. ZoomFactor='FitSystem' alone without arrangeSystem often leaves the model in a small corner of the canvas.

  • P86: Two-pass simulation + don't over-iterate. (a) StopTime for lock = min(3 × t_lock_target, 50µs) — NOT 5 × (12/BW) which over-allocates. At 5 GHz, every µs = ~1s wall-clock. (b) If first attempt PASSES with >3x margin, STOP — do NOT sweep BW or iterate. The BW formula already gives a good design. Only iterate when first attempt FAILS. (c) Never enable PhaseNoiseOption unless user explicitly asks for PN.

  • P87: HoldOffTime MUST be < StopTime — otherwise testbench fires a blocking warning dialog and reports no measurements. When P86 shortens StopTime, you MUST also shorten HoldOffTime to match. Use: holdOff = min(1.5*estLockTime, 0.8*StopTime). The 80% cap ensures the testbench always has measurement time.

  • P88: VCO consistency — validate standalone, then verify same params in PLL. When the datasheet provides VCO phase noise data: (1) Build a standalone VCO + VCO Testbench model, call msblks.VCO.estimatePhaseNoiseCore(f0, Foffset, PN) to get PeriodJitter and CornerFrequency, set them on the VCO, simulate, and confirm measured PN matches datasheet within ±3 dB. (2) After assembling the full PLL, probe the internal VCO and VERIFY its PeriodJitter and CornerFrequency match the validated values.

  • P93: PLL Testbench reports LockTime = 0 means Vctrl ripple exceeds frequency error tolerance. The TB mask parameter is FreqErrorTol (default 1 MHz). In Fractional-N PLLs, DSM quantization noise causes residual Vctrl ripple that can exceed this tolerance even when the PLL is locked. When LockTime = 0:

    1. Measure steady-state Vctrl ripple (peak-to-peak in last 50% of sim) and convert to frequency: Δf = Kvco × Vctrl_pp.

    2. Inform the user: explain that ripple (±X MHz) exceeds the FreqErrorTol (Y MHz), and ask whether to (a) increase error tolerance, or (b) keep it strict and redesign the loop filter.

    3. If user accepts relaxed tolerance: set_param(tb, 'FreqErrorTol', num2str(newTol)) where newTol = 1.5–2× the observed ripple, re-simulate.

    4. If user demands strict tolerance: narrow loop BW (reduces DSM noise passthrough), increase filter order, or add a 4th pole to attenuate high-frequency DSM energy. Re-simulate and verify both lock time and ripple. Do NOT silently switch to alternative measurement methods without first diagnosing and communicating the root cause to the user.

  • P96: lockTimeMeasure expects column vectors. When using To Workspace timeseries data, the .Data field may be N-D. Always squeeze and columnize: v = squeeze(Vctrl.Data); v = v(:); t = Vctrl.Time(:); before passing to lockTimeMeasure(v, t, errTol).

  • P97: "Apply or cancel unapplied changes" error blocks simulation. This occurs when a block dialog is open in the MATLAB UI. Fix: call close_system([model '/BlockName']) to close the dialog, then retry set_param and sim.

  • P98: Always use msblks.utilities.acStopTime(avg, RBW, holdoff) for PN measurement StopTime. Do NOT compute manually as holdoff + avg/RBW — the utility adds margin for spectral windowing. Manual calculation underestimates by ~30-40%.

  • P99: Fractional-N DSM spurs appear at multiples of fPFD/denominator. For N=612.5 (frac=0.5, denom=2), spurs appear at fPFD/2 = 5 MHz and its sub-harmonics. When reporting PN at offsets that coincide with spur frequencies, clearly label them as "spur level" vs "PN floor" (measured between spurs). The PN floor is the meaningful noise metric; spur levels are a separate specification.

  • P100: TargetPhaseNoiseVector does NOT accept -inf. The mask validates for finite values only. When no PN targets are specified, use -999 (dBc/Hz) as a placeholder that will never trigger a failure: mat2str(-999*ones(1, numel(pnOffsets))). Update P94 accordingly — -inf causes a mask error.

  • P101: Pass 2 HoldOffTime must use the MEASURED lock time from Pass 1, not the pre-sim estimate. After Pass 1 confirms lock at e.g. 1.0 µs, set Pass 2 HoldOffTime = 1.5 × 1.0 µs = 1.5 µs. Do NOT carry forward the initial estimate (which used (4/Fc)*3 and may be 5-7× too large). Excessive holdoff wastes measurement window and can push StopTime requirements higher unnecessarily.

  • P102: SpectralAverages defaults to 4 on the PLL Testbench mask — explicitly set to 2 (P61). The skill mandates starting with 2 averages for faster simulation. If you don't explicitly set_param(tb, 'SpectralAverages', '2'), the mask default of 4 applies, doubling PN sim time. Only increase if user requests smoother results.

  • P103: When tuning an existing PLL model, NEVER estimate lock time from Vctrl settling. Run sim(model) and read the PLL Testbench result: ud = get_param(tbBlk, 'UserData'); lockTime = ud.lockTime;. The testbench uses frequency-error-based detection (FreqErrorTol) which is the only valid measurement. Manual Vctrl analysis gives different (incorrect) results because voltage tolerance doesn't map linearly to frequency error across the VCO tuning curve.

  • P104: When an existing model has NO PLL Testbench (or no connected reference source), you CANNOT determine fComp from the model. The RefFreq parameter is ONLY used for estimatePLLPhaseNoise estimation — it does NOT define the actual reference clock. Do NOT guess or calculate fComp from Fo/N. Instead, ASK the user: "What is the reference frequency (fComp) for this PLL?" You cannot design, simulate, or meet any spec without knowing fComp.

  • P105: Dual Modulus Prescaler constraints: P > S > 0, all positive integers. The SwallowCounter (S) must be strictly positive — the mask rejects S=0. The ProgramCounter (P) must be strictly greater than S. When choosing P, N, S for a target divide ratio (PN+S = Ntarget), enumerate valid combinations satisfying P > S > 0 BEFORE calling set_param. Safe setting order: set Nmin='1' first (P57), then S (while default P is still large), then P (verify P > S), then Nmin to final value. Example for Ntarget=40: P=7, N=5, S=5 (7>5>0, 75+5=40).

  • P106: pllOpenLoopPlot may crash with ylim error when phase <= -180 degrees. The MSB function pllOpenLoopPlot has an edge case where ylim([-180 max(...)]) fails if the computed phase at the midpoint is <= -180. Fallback: compute Bode manually using the loop filter impedance Z(s) and open-loop gain G(s) = IcpKvcoZ(s)/(N*s). Use logspace frequency sweep, compute magnitude/phase, find crossover by interpolation. Do NOT reach for Control System Toolbox (tf, bode) — it is not required and may not be installed. Example fallback:

    f = logspace(3, 9, 1000); s = 1j*2*pi*f;
    Z = (1 + s*R2*C2) ./ (s*(C1+C2+C3) .* (1 + s*R2*C1*C2/(C1+C2+C3)) .* (1 + s*R3*C3));
    G = Icp * Kvco * Z ./ (N * s);
    mag_dB = 20*log10(abs(G)); phase_deg = angle(G)*180/pi;
    % Find fc (0 dB crossing) and PM (180 + phase at fc) by interpolation

Tuning an Existing PLL to Meet Specs

When the user has an existing model and wants to meet a new spec (lock time, phase noise, spurs):

  1. Probe first — extract current parameters (get_param on PLL block: Fc, Phi, N, OutputCurrent, Kvco, filter components)

  2. Check for PLL Testbench — if no testbench exists, check if the PLL input port is connected. If unconnected or no reference source, ASK the user for fComp (P104). Do not proceed without it.

  3. Baseline sim — run sim(model) and read PLL Testbench UserData for lock time, frequency, phase noise. This is the only valid baseline.

  4. Identify the lever — for lock time: increase Fc; for phase noise: decrease Fc or increase filter order; for spurs: increase filter order or reduce Fc

  5. Redesign — set new Fc (and Phi if needed), keep CompSelectionMethod = 'Automatic' so the block recomputes filter components

  6. Re-simulate — run again, read testbench UserData. Iterate until spec is met.

  7. Report trade-offs — wider BW improves lock time but degrades close-in phase noise; narrower BW improves PN but slows lock

Key formula: lock_time ≈ 12/Fc (conservative rule of thumb). Use it only for initial Fc sizing, then verify with testbench.


High-Frequency PLL Modeling (>4 GHz)

Key rules:

  1. Flattening is safe at any VCO frequency if PFD timing is scaled

  2. Scale PFD timing: PropDelay < VCO half-period / 10

  3. Set MaxFreqInterest = 2*fVco

  4. Expect long sim times: 16.5 GHz -> ~200-260 s for 60 us stop time

  5. In-band PN dominated by DSM -- validate only at far offsets (>10x BW)

  6. Far-offset jitter matches datasheet well

  7. CP impairment (EnableCurrentImpairments) causes ~15x slowdown at 8 GHz (measured: 17s vs 267s for 1 µs sim). For spur analysis at high VCO frequencies, use estimatePLLPhaseNoise instead of transient simulation with CP impairment enabled.

Example: ADF4382 at 16.5 GHz
set_param(blk, 'Fo', '16.5e9', 'Kvco', '100e6', ...
    'PropDelay', '3e-12', 'RiseFallTime', '3e-12', ...
    'MaxFreqInterest', '33e9', 'MaxFreqInterestCp', '33e9');
set_param(tb, 'Fo', '125e6', 'ExpectedFreq', '16.5e9', ...
    'SampleRate', '132e9');

Noise Budget Reference (at 100 kHz, near 60 kHz loop BW)

SourceImpact
CP timing impairments+12 dB (default values too aggressive for ADF4351)
LF thermal noise+4 dB (real physics, keep enabled)
PFD edge impairments<0.5 dB (negligible)
CP broadband noise (Si_cp)<1 dB (PNSYNTH=-220 is very low)
DSM/measurement gap~4 dB above analytical (normal, reduces with more averages)

Copyright 2026 The MathWorks, Inc.

Requirements and compatibility

Written for: Claude Code

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Names Claude Code tools, Needs an MCP server

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
MathWorks
Publisher
MathWorks (Official)
Source
matlab/matlab-agentic-toolkit · skills-catalog/rf-and-mixed-signal/matlab-model-ams-systems · commit 2a7f215
Licence
BSD 2-Clause License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by MathWorks or MathWorks.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-model-ams-systems.zip