Matlab Model Ams Systems
MathWorksOfficialCreated by MathWorks
- Skill
- Workflow
- Software development
- BSD-2-Clause
- No issues found
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
Download the skill as a ZIP:
https://autogineer.com/agent-skills/matlab/matlab-model-ams-systems/downloadUnzip 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
estimatePLLPhaseNoisedirectly)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)
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:
Output frequency (or frequency range)
Reference frequency (flag if N > 200 — high in-band noise penalty)
Architecture (Integer-N / Frac-N / auto — may be predetermined by N)
Lock time target
Phase noise / jitter / spur targets (or confirm "none")
Charge pump current (offer typical value as default)
VCO requirements (Kvco, phase noise profile — offer rule-of-thumb)
Loop filter preference (order, BW override)
Any other requirements?
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).
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.
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/pllCloseLoopPlotviaexportgraphics(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 withweb(reportPath, '-browser').Figures must be visible -- After simulation, call
set(0,'DefaultFigureVisible','on')and ensure all plot figures have'Visible','on'. Calldrawnowto force rendering. The MCP MATLAB server defaults toVisible='off'.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/pllCloseLoopPlotStep C — Sim start:
Simulating Pass 1 (lock time)... StopTime=9µsStep 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
msbPllFoundationlibrary)Control System Toolbox (for
estimatePLLPhaseNoisevalidation, 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:
Gather specs (Directive 1) → present Design Plan (Directive 5, Step A)
If VCO PN data available: validate VCO standalone first (see below)
Select architecture block from
msbPllArchitectures(Strategy A — DEFAULT)Design loop filter:
N ≤ 50:
CompSelectionMethod='Automatic'withFcandPhiN > 50 (P79):
thirdOrderPassiveFilterDesign→CompSelectionMethod='Manual'N threshold applies to effective N (including fractional part)
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:
Probe — extract current params:
Fc,Phi,N,OutputCurrent,Kvco,CompSelectionMethod, filter components viaget_paramCheck for PLL Testbench — if missing or PLL input unconnected, ASK the user for fComp (P104). Add a PLL Testbench if needed.
Baseline sim —
sim(model), readget_param(tbBlk, 'UserData')for lock time, frequency, phase noise. This is the ONLY valid baseline (P103).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 NSpurs too high → increase filter order or narrow
Fc
Redesign — set new
Fc(andPhiif needed), keepCompSelectionMethod='Automatic'so the block recomputes filter componentsRe-simulate — read testbench UserData. Iterate until spec is met.
Report — before/after comparison with trade-off notes
Key rules:
NEVER estimate lock time from Vctrl settling (P103)
NEVER guess fComp from
Fo/NorRefFreqparam (P104)Cap
FcatfPFD/10for stabilityUse
lock_time ≈ 12/Fconly 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:
| 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.
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 subsystemmsblks.PLL.estimatePhaseNoise(gcb)-- analytical PN estimationmsblks.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 params3.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_codecall (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 viamcp__matlab__run_matlab_file(keeps terminal clean — no code dump), (4) verify. Usingrun_matlab_fileinstead ofevaluate_matlab_codefor 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:
new_system+ solver config (VariableStepDiscrete,ReturnWorkspaceOutputs='on')add_blockfrommsbPllArchitectures/<type>Set divider:
Nmin='1'first, thenN, thenNminto final value (P57/P92)Set VCO params:
Kvco,Fo,OutputCurrent,AddPhaseNoise,RefFreqLoop filter:
thirdOrderPassiveFilterDesignfor N>50 (P79), elseAutomaticPFD timing:
PropDelay = max(50e-12, min(5e-12, 1/(2*fVCO)/10)),MaxFreqInterest = 2*fVCO(50ps floor — block rejects smaller values)Enable
lf_out='on'for Vctrl probeAdd PLL Testbench (
Fo=fPFD,ExpectedFreq=fVCO,SampleRate=8*fVCO)Set
SpectralAverages='2'(P102: mask default is 4),LockTimeOption='on',PhaseNoiseOption='off'(P83)StopTime = min(3*t_lock, 50e-6),HoldOffTime = min(1.5*estLock, 0.8*StopTime)Set paired vectors via
Simulink.Mask.get:PhaseNoiseFreqOffset,TargetPhaseNoiseVector(P71, P100: use-999if no targets — mask rejects-inf)Connect: TB/1→PLL/1, PLL/1→TB/1, PLL/2→Scope+ToWorkspace
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
pllOpenLoopPlotcrashes (ylim error at phase <= -180°): use manual Bode fallback per P106 — compute Z(s), G(s) vialogspacesweep. 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 vectorP103: 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 noiseHappy 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
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md22.9 KiB
- manifest.yaml647 B
- references/assembly-code.md8.7 KiB
- references/datasheet-extraction.md2.9 KiB
- references/iteration-algorithm.md4.1 KiB
- references/modeling-pll-datasheet-validate.md16.9 KiB
- references/pitfalls.md23.0 KiB
- references/probing-simulink-models.md6.3 KiB
- references/stability-analysis.md6.5 KiB
- references/validate.md4.0 KiB
- scripts/probeSlxModel.m6.6 KiB
- scripts/quickProbe.m787 B
references/validate.md
Reference: Validation Detail (Phases 7-8 Detail)
Loaded by the validate skill for extended code examples.
Zero-Crossing Capture (Triggered Subsystem Method)
Preferred over logging full waveform. More precise, more memory-efficient.
% Create Triggered Subsystem
trigSys = [model '/ZC Capture'];
add_block('simulink/Ports & Subsystems/Triggered Subsystem', trigSys);
set_param(trigSys, 'Position', [700, 100, 880, 200]);
set_param([trigSys '/Trigger'], 'TriggerType', 'rising');
% Remove default In1/Out1 wiring
delete_line(trigSys, 'In1/1', 'Out1/1');
delete_block([trigSys '/In1']);
delete_block([trigSys '/Out1']);
% Add Digital Clock -> To Workspace inside
add_block('simulink/Sources/Digital Clock', [trigSys '/Clock']);
set_param([trigSys '/Clock'], 'SampleTime', '-1', ...
'Position', [50, 50, 130, 80]);
add_block('simulink/Sinks/To Workspace', [trigSys '/Log ZC']);
set_param([trigSys '/Log ZC'], 'VariableName', 'zc_times', ...
'SaveFormat', 'Array', 'Position', [200, 50, 300, 80]);
add_line(trigSys, 'Clock/1', 'Log ZC/1');
% Connect VCO output to trigger port
rt = {'autorouting', 'smart'};
add_line(model, 'VCO/1', 'ZC Capture/Trigger', rt{:});After simulation, retrieve timestamps: zc_times = simOut.zc_times;
(goes to simOut with ReturnWorkspaceOutputs='on', P31).
PLL Testbench Configuration for Architecture Blocks (P43)
tbPath = [model '/PLL Testbench'];
add_block('msbPllMeasurements/PLL Testbench', tbPath, ...
'Position', [80, 50, 430, 350]);
% Set via mask to avoid callback conflicts
mask = Simulink.Mask.get(tbPath);
mask.getParameter('PhaseNoiseFreqOffset').Value = mat2str(Foffset);
mask.getParameter('TargetPhaseNoiseVector').Value = mat2str(phaseNoise);
mask.getParameter('ResBandwidth').Value = num2str(min(Foffset)/2);
set_param(tbPath, ...
'Fo', num2str(fRef), ... % Reference freq (NOT fVco)
'ExpectedFreq', num2str(fVCO), ...
'TargetFreq', num2str(fVCO), ...
'SampleRate', num2str(8*fVCO), ...
'SpectralAverages', '2', ...
'HoldOffTime', num2str(5*lock_time), ...
'PlotAndLogPhaseNoise', 'on', ...
'PhaseNoiseOption', 'on');Retrieving Testbench Results from Model Workspace (P53)
% Get SID suffix for variable naming
sid = Simulink.ID.getSID(tbPath);
sidParts = split(sid, ':');
sidSuffix = sidParts{2};
% Read results from model workspace
mdlWs = get_param(model, 'ModelWorkspace');
freq = evalin(mdlWs, ['Frequency_' sidSuffix]);
lockTime = evalin(mdlWs, ['LockTime_' sidSuffix]);Post-Simulation Results Plotting (P68)
MCP preserves only one figure. Create all results in a single tiledlayout:
set(0, 'DefaultFigureVisible', 'on');
pnOut = evalin('base', 'pll_phase_noise_out');
f = pnOut.PnFOffset; pn = pnOut.Pn;
validIdx = f > 0; f = f(validIdx); pn = pn(validIdx);
fig = figure('Name', 'PLL Results', 'Position', [100 150 1200 500], 'Visible', 'on');
tiledlayout(1, 2, 'TileSpacing', 'compact');
nexttile;
semilogx(pnOut.phaseNoiseFreq, pnOut.phaseNoiseLevel, 'b-o', 'LineWidth', 2);
xlabel('Frequency Offset (Hz)'); ylabel('Phase Noise (dBc/Hz)');
title('Measured Phase Noise'); grid on;
nexttile;
semilogx(f, pn, 'b-', 'LineWidth', 1.2);
xlabel('Frequency Offset (Hz)'); ylabel('Phase Noise (dBc/Hz)');
title('Full Spectrum (Spur Analysis)'); grid on;
drawnow;Dual-Modulus Prescaler Spur Analysis (P66)
% Sub-harmonic spurs occur at fRef*k/N (especially fRef/P)
% Example: P=4, P+1=5, S=2, N=12 -> divide-by-50
% Spurs at 20 MHz (fRef/5), 40 MHz, 80 MHz in addition to fRef spur
% Include sub-harmonic frequencies in offset vector
fRef = 100e6; P = 4;
subHarmonics = fRef .* (1:P) ./ (P+1); % [20e6 40e6 60e6 80e6]
Foffset = sort(unique([1e6 10e6 subHarmonics fRef 1.2*fRef]));
% Examine full spectrum for spurs
pnOut = evalin('base', 'pll_phase_noise_out');
semilogx(pnOut.PnFOffset, pnOut.Pn); % 301-point array shows all spursCopyright 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