Matlab Model Rf
MathWorksOfficialCreated by MathWorks
- Skill
- Guidelines
- Science and research
- 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 approach to utilizing MATLAB's RF Toolbox and RF Blockset for end-to-end RF system development. It covers workflows ranging from measured S-parameter data validation and network conversions to complex circuit-level design, amplifier stability analysis, and time-domain Circuit Envelope simulation. The documentation emphasizes best practices for script-based workflows, proper element handling, and avoiding common pitfalls in RF parameter manipulation and system modeling.
What it does
- Validates and processes measured S-parameter data from Touchstone files.
- Performs network parameter conversions and mixed-mode analysis.
- Enables RF signal chain design and cascaded budget analysis.
- Supports circuit-level composition and impedance matching network design.
- Facilitates amplifier stability analysis and mixer intermodulation planning.
- Provides tools for rational fitting and time-domain system simulation.
When to use it
- When working with measured S-parameter data for validation or de-embedding.
- When designing RF signal chains and performing cascaded budget analysis.
- When composing arbitrary RF circuits using node-based netlists.
- When analyzing amplifier stability or mixer spur performance.
- When performing time-domain signal integrity or Circuit Envelope simulations.
Advantages
- Unified workflow for both passive and active RF device characterization.
- Strict adherence to MATLAB identifier and object handling rules prevents silent errors.
- Comprehensive support for modern visualization tools like tiledlayout and smithplot.
- Clear separation between script-based design workflows and interactive analysis.
- Detailed guidance on avoiding common errors in port ordering and parameter units.
Usage examples
- “How do I load an S-parameter file and plot it on a Smith chart?”
- The agent will guide you to use sparameters() to load the file, followed by smithplot() for visualization, ensuring you handle reference impedance correctly via newref() if needed.
- “Calculate the cascaded gain and noise figure for my RF chain.”
- The agent will help you define elements using rfbudget, ensuring you set the SignalBandwidth and use clone() for reused elements, then run the budget analysis.
- “How do I analyze the stability of an amplifier?”
- The agent will instruct you to use stabilityk and stabilitymu, and calculate power gain using powergain with the correct linear-to-dB conversion.
- “I need to export my S-parameters to a new file.”
- The agent will provide the rfwrite command, specifically reminding you to include 'ForceOverwrite', true to avoid interactive dialogs.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/matlab/matlab-model-rf/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-model-rf.zip -d .agents/skills
Documentation by MathWorks
RF Toolbox and RF Blockset
Design, analyze, and simulate RF systems in MATLAB -- from measured S-parameter data through full time-domain Circuit Envelope simulation. One unified workflow covering passive networks, active device characterization, system cascade budgets, and behavioral time-domain modeling.
When to Use
Measured data workflows
Loading Touchstone files (.s1p through .snp), validating quality (passivity, causality, IEEE P370)
Plotting on Smith charts and rectangular plots, interpolating, re-referencing impedance
Converting between S, Z, Y, ABCD, T, H, G parameters; computing mixed-mode differential
Cascading and de-embedding S-parameter networks; fixture removal
System design and analysis
Building RF signal chains from behavioral elements (amplifier, modulator, rffilter, nport, etc.)
Computing cascaded gain, noise figure, IP3, SNR, output power with rfbudget
Comparing Friis vs Harmonic Balance solver accuracy
Exporting to RF Blockset Simulink models, Communications Toolbox, or MATLAB scripts
Circuit-level design
Composing arbitrary RF circuits with node wiring (SPICE-like netlist)
Designing impedance matching networks (L, Pi, Tee topologies, Richards stubs)
Analyzing amplifier stability (K-factor, mu), power gain, and matching conditions
Mixer intermodulation analysis and spur-free IF frequency planning
Time-domain and signal integrity
Fitting S-parameters to rational models; computing TDR, impulse, step responses
Exporting broadband circuit models to SPICE or Verilog-A
Building SI channel models from nport blocks, lossy transmission lines, and parasitics
Processing complex baseband signals through rf.Amplifier, rf.Mixer, rf.Filter System Objects
Full Circuit Envelope time-domain simulation via rfsystem (no Simulink knowledge required)
When NOT to Use
Antenna design and radiation patterns -- use Antenna Toolbox
RF propagation modeling (path loss, fading, ray tracing) -- use Communications Toolbox or Phased Array System Toolbox
SerDes/high-speed serial link equalization (FFE, CTLE, DFE, IBIS-AMI) -- use SerDes Toolbox
Radar waveform design or phased arrays -- use Phased Array System Toolbox
Must-Follow Rules
These apply across ALL RF Toolbox workflows. Violating them produces silent errors or blocks execution.
Universal
rfwriteblocks on existing files -- Always pass'ForceOverwrite', true. Without it, MATLAB opens an interactive overwrite dialog that halts unattended execution.Elements cannot be reused -- The same element object cannot appear twice in an rfbudget or circuit. Use
clone(element)for independent copies.Element Name must be a valid MATLAB identifier -- No spaces, no special characters. Use
'IFAmp'not'IF Amp'.Use
tiledlayout/nexttile-- Notsubplot. For all multi-panel figures.rfparamreturns complex, not dB -- Always use20*log10(abs(rfparam(...)))for dB magnitude.
S-Parameters and Network Parameters
sparameters(filename, Z0)is invalid -- Cannot pass reference impedance at load time. Load first, thennewref(s, Z0).rfinterp1interpolates real/imag independently -- Not magnitude and angle. Can produce artifacts near sharp resonances.Frequency alignment required for cascade/de-embed --
cascadesparamsanddeembedsparamsrequire identical frequency vectors. Alwaysrfinterp1to a common grid first.deembedsparamsalways requires 3 arguments --(sMeasured, sFixture1, sFixture2). For one-sided, pass an ideal thru for the unused side.Mixed-mode port ordering is the #1 error source --
s2sddoption 1 (default) treats ports 1,2 as positive and 3,4 as negative. Verify which option matches your VNA port numbering.snp2smpargument order: ports before impedance --snp2smp(s, portList, Z0), notsnp2smp(s, Z0, portList).
rfbudget and Elements
SignalBandwidthis required -- The 4th positional arg torfbudget. Without it, NF/IP3/SNR remain empty.Passive NF equals loss -- For
rfelement, NF should equalabs(Gain). Preferattenuatorwhich handles this automatically.nportName is positional --nport('file.s2p', 'MyName'), not name-value syntax.rffilter:
ResponseTypeis shape,FilterTypeis algorithm --rffilter('FilterType', 'Bandpass')errors. Userffilter('ResponseType', 'Bandpass').show(b)opens a GUI -- Produces no command-window output. Use properties (b.TransducerGain,b.NF) for programmatic access.
Circuit Composition
setports/setterminalscan only be called once -- Plan topology before defining terminals.2-port RF elements use 4-node mapping --
add(ckt, [in out inRef outRef], elem)for amplifier, modulator, nport, all txline types. Primitive 2-terminal elements (resistor, capacitor, inductor) use 2-node mapping.Primitive constructors are positional --
resistor(100, 'R1'), notresistor('Resistance', 100).setterminalstakes a node vector --setterminals(ckt, [1 2]), notsetterminals(ckt, 1, 2).All txline constructors use name-value pairs only -- No positional arguments.
Amplifier Analysis
powergaingain type string must be last --powergain(s, 50, 50, 'Gt'), notpowergain(s, 'Gt', 50, 50).powergainreturns linear, not dB -- Convert with10*log10(g)(power gain uses 10x, not 20x).Gmagreturns NaN when conditionally stable -- UseGmsgat frequencies where K < 1.
Rational Fitting
rationalvsrationalfit-- Userationalfor new code (AAA). Userationalfitonly for delay extraction.Single-param fit returns plain vectors; multi-port returns cell arrays -- Always check with
iscell(result).freqresptakes Hz -- Not rad/s. Passs.Frequenciesdirectly.
System Objects (rf.*)
rf.Amplifier/rf.Mixer use 1-ohm power --
Vin = sqrt(Pin_W). This differs from rfsystem which uses 50-ohm.rf.Filter frequencies are ABSOLUTE RF --
PassFreq_bp=[2.395e9 2.405e9]means absolute GHz. Not baseband offsets.Properties locked during use -- Call
release(obj)before modifying Nontunable properties.
rfsystem
Requires rfbudget --
rfsystemtakes an rfbudget, not raw elements.close_systemneeds save flag -- Useclose_system(rfs, 0)to discard changes.IdealizedBaseband only supports amplifier/modulator/rffilter/nport -- Other elements require CircuitEnvelope.
Workflow Quick Reference
| Task | Entry Point | Details |
|---|---|---|
| Load/plot S-parameters | sparameters, rfplot, smithplot | reference/sparameters-io.md |
| Convert S/Z/Y/ABCD, mixed-mode | zparameters, s2sdd, snp2smp | reference/network-conversions.md |
| Cascade or de-embed networks | cascadesparams, deembedsparams | reference/cascade-deembed.md |
| Create rfbudget elements | amplifier, modulator, rffilter, etc. | reference/rfbudget-elements.md |
| Run cascade budget analysis | rfbudget, rfplot(b, 'Pout') | reference/rfbudget-analysis.md |
| Compose RF circuits | circuit, add, setports | reference/circuit-composition.md |
| Design matching networks | matchingnetwork, richards | reference/matching-networks.md |
| Analyze amplifier stability/gain | stabilityk, powergain, gammams | reference/amplifier-analysis.md |
| Mixer spurs and IF planning | mixerIMT, OpenIF | reference/mixer-analysis.md |
| Fit rational models, TDR | rational, stepresp, generateSPICE | reference/rational-fitting.md |
| Build SI channel models | nport + txlineWRLGC + circuit | reference/si-channel-modeling.md |
| Process complex baseband | rf.Amplifier, rf.Mixer, rf.Filter | reference/baseband-processing.md |
| Time-domain system simulation | rfsystem, Circuit Envelope | reference/system-simulation.md |
Conventions
Code Style
Use
tiledlayout/nexttilefor multi-panel figures (notsubplot)Always label axes with units (GHz, dB, ns, dBm) and include figure titles
Name elements descriptively for readable topology (
'LNA','DCBlock','PCBTrace')Use
clone()liberally for element reuse
Script-First Workflow
For design, analysis, or sweep tasks -- write code to .m files on disk, not inline snippets. For quick one-off checks, inline evaluate_matlab_code is fine.
Modern APIs
tiledlayout/nexttileinstead ofsubplotdatetimeinstead ofdatenumrationalinstead ofrationalfit(unless delay extraction needed)smithplotinstead ofsmithrfplotfor S-parameter visualization (handles dB conversion automatically)
References
Load the relevant reference file before writing code for a specific workflow. Each reference contains correct calling conventions, constructor arguments, property names, gotchas, and executable code patterns.
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md9.8 KiB
- manifest.yaml536 B
- reference/amplifier-analysis.md9.3 KiB
- reference/amplifier-models.md2.8 KiB
- reference/amplifier-nonlinear-models.md6.2 KiB
- reference/baseband-processing.md18.5 KiB
- reference/cascade-deembed.md9.0 KiB
- reference/circle-computations.md7.3 KiB
- reference/circuit-composition.md14.1 KiB
- reference/ifft-step-response.md16.8 KiB
- reference/lumped-to-distributed.md2.7 KiB
- reference/matching-networks.md10.8 KiB
- reference/mixer-analysis.md11.0 KiB
- reference/network-conversions.md9.6 KiB
- reference/rational-fitting.md19.8 KiB
- reference/rfbudget-analysis.md8.4 KiB
- reference/rfbudget-elements.md16.8 KiB
- reference/rffilter-synthesis.md2.8 KiB
- reference/si-channel-modeling.md17.8 KiB
- reference/sparameters-io.md12.0 KiB
- reference/system-simulation.md12.9 KiB
- reference/time-domain-analysis.md3.0 KiB
- reference/transmission-lines.md2.8 KiB
reference/rational-fitting.md
Rational Fitting and Time-Domain Analysis
Fit S-parameter data to rational function models, compute time-domain responses (TDR, impulse, step), and export to SPICE/Verilog-A.
The rational Object (R2020a+, AAA algorithm)
Prefer rational over rationalfit (vector fitting). Both provide the same analysis methods (impulse, stepresp, timeresp, zpk, generateSPICE, pwlresp, iscausal, ispassive, makepassive, passivity, freqresp, abcd, writeva). The advantage of rational is that it tends to converge more robustly and faster. The advantage of rationalfit is that it enables delay removal.
Note: rationalfit still ships and uses the vector-fitting algorithm. It returns the legacy rfmodel.rational object. Use rational (without the "fit" suffix) for new code unless you specifically need vector fitting or delay extraction.
Input Forms
| Input | Returns | Time-domain output |
|---|---|---|
rational(sparametersObj) | N-port fit | Cell arrays {N,N} -- access as y{i,j}, t{i,j} |
rational(freq, dataVector) | 1-port fit | Plain vectors -- use directly as y, t |
Critical: For single-parameter fits (rational(freq, s21)), impulse/stepresp/timeresp return plain vectors. Cell arrays {N,N} are returned ONLY when fitting an entire sparameters object.
Quick Recipes
Use these complete blocks directly. Do NOT assemble from individual pieces.
Impulse Response
s = sparameters('channel.s2p');
s21 = rfparam(s, 2, 1);
[fit21, errdb] = rational(s.Frequencies, s21);
fprintf('Fit: %d poles, %.1f dB error\n', fit21.NumPoles, errdb);
% Single-parameter fit returns plain vectors (NOT cell arrays)
[yImp, tImp] = impulse(fit21, 1e-12, 5000); % (fit, sampleTime, numPoints)
figure; plot(tImp*1e9, real(yImp));
xlabel('Time (ns)'); ylabel('Amplitude'); title('Channel Impulse Response');TDR with Impedance Profile
s = sparameters('dut.s2p');
s11 = rfparam(s, 1, 1);
tdrFreqData = (s11 + 1) / 2; % Voltage TDR in frequency domain
tdrFit = rational(s.Frequencies, tdrFreqData, 'Qlimit', inf, 'TendsToZero', false);
% stepresp: simplest TDR computation
velocity = 2e8; % m/s (adjust for your medium)
fmax = s.Frequencies(end);
tRise = 1 / fmax; % Rise time from measurement bandwidth
Ts = 1e-11; N = 10000;
[tdr, tOut] = stepresp(tdrFit, Ts, N, tRise);
% Convert TDR voltage to impedance
s11_recovered = 2*real(tdr) - 1;
Z = 50 * (1 + s11_recovered) ./ (1 - s11_recovered);
% Convert time to distance (one-way)
distance = tOut * velocity / 2;
minFeature = velocity * tRise / 2;
fprintf('Bandwidth: %.1f GHz, Rise time: %.1f ps, Spatial resolution: %.1f mm\n', ...
fmax/1e9, tRise*1e12, minFeature*1e3);
% Detect discontinuities: find where impedance deviates from Z0
Z0 = 50; threshold = 5;
discontinuityIdx = find(abs(Z - Z0) > threshold);
if ~isempty(discontinuityIdx)
fprintf('discontinuity at %.1f cm (Z = %.1f ohms)\n', ...
distance(discontinuityIdx(1))*100, Z(discontinuityIdx(1)));
end
figure; plot(distance*100, Z);
xlabel('Distance (cm)'); ylabel('Impedance (\Omega)'); title('TDR Impedance Profile');
yline(Z0, '--k', 'Z_0'); yline(Z0+threshold, ':r'); yline(Z0-threshold, ':r');Spatial resolution: TDR cannot resolve features smaller than velocity * tRise / 2. The rise time is limited by measurement bandwidth -- a 10 GHz measurement gives ~1 cm resolution. Features smaller than this appear smeared. Do not interpret ringing artifacts as discontinuities. See reference/ifft-step-response.md for the pure-iFFT alternative when rational fitting is not needed.
Fit, Verify, Export
s = sparameters('measured.s2p');
[fit, errdb] = rational(s, 'Tolerance', -60);
fprintf('Poles: %d, Error: %.1f dB, Passive: %d\n', ...
fit.NumPoles, errdb, ispassive(fit));
if ~ispassive(fit), fit = makepassive(fit); end
% Verify in frequency domain -- include intermediate and out-of-band points
fVerify = linspace(0, 2*s.Frequencies(end), 10001)';
resp = freqresp(fit, fVerify);
figure; tiledlayout(1,2);
nexttile; plot(s.Frequencies/1e9, 20*log10(abs(rfparam(s,2,1))), '-o', ...
fVerify/1e9, 20*log10(abs(squeeze(resp(2,1,:)))), '--');
xlabel('Frequency (GHz)'); ylabel('|S21| (dB)'); legend('Original','Fit');
nexttile; plot(s.Frequencies/1e9, 20*log10(abs(rfparam(s,1,1))), '-o', ...
fVerify/1e9, 20*log10(abs(squeeze(resp(1,1,:)))), '--');
xlabel('Frequency (GHz)'); ylabel('|S11| (dB)'); legend('Original','Fit');
% Export
generateSPICE(fit, 'model.sp');
writeva(fit, 'model.va', 'in', 'out', 'electrical');Recipe: Extrapolate to DC or Beyond Measured Range
s = sparameters('measured.s2p'); % e.g., 10 MHz to 20 GHz
[fit, errdb] = rational(s);
% Evaluate at any frequencies -- freqresp takes Hz
freqExtended = linspace(0, 40e9, 401)'; % DC to 40 GHz
resp = freqresp(fit, freqExtended); % N-by-N-by-K array
s21_extrap = squeeze(resp(2,1,:));
figure; plot(freqExtended/1e9, 20*log10(abs(s21_extrap)));
xlabel('Frequency (GHz)'); ylabel('|S21| (dB)'); title('Extrapolated Response');Recipe: Extract Channel Delay
s = sparameters('channel.s2p');
s21 = rfparam(s, 2, 1);
% Use rationalfit (not rational) for delay extraction
fit = rationalfit(s.Frequencies, s21, 'DelayFactor', 1);
fprintf('Channel delay: %.3f ns\n', fit.Delay * 1e9);Recipe: Synthetic Cable with Discontinuity (for TDR Testing)
% Create S-parameters for cable with impedance discontinuity
freq = linspace(1e6, 10e9, 501)';
Z0 = 50; Zdiscontinuity = 75; vel = 2e8;
len1 = 1.5; len2 = 0.3; len3 = 1.2; % meters (discontinuity at 1.5m, 0.3m long)
ckt = circuit('discontinuityCable');
tl1 = txlineDelayLossless('Name', 'Pre', 'Z0', Z0, 'TimeDelay', len1/vel);
tl2 = txlineDelayLossless('Name', 'Discontinuity', 'Z0', Zdiscontinuity, 'TimeDelay', len2/vel);
tl3 = txlineDelayLossless('Name', 'Post', 'Z0', Z0, 'TimeDelay', len3/vel);
add(ckt, [1 2 3 4], tl1); add(ckt, [3 4 5 6], tl2); add(ckt, [5 6 7 8], tl3);
setports(ckt, [1 2], [7 8]);
s = sparameters(ckt, freq);
% Now apply TDR recipe from aboveBuilding synthetic circuits for test data: For node mapping rules (4-node for 2-port RF elements, 8-node for 4-port), clone() for element reuse, and multi-port setports patterns, see reference/circuit-composition.md.
Recipe: Synthetic Lossy Channel (No Circuit Construction)
freq = linspace(1e9, 20e9, 201)';
delay = 500e-12; % propagation delay
s21 = reshape(10.^(-0.5*(freq/1e9)/20) .* exp(-1j*2*pi*freq*delay), 1, 1, []);
s11 = reshape(0.05 * exp(-1j*2*pi*freq*delay*0.1), 1, 1, []);
data = [s11 s21; s21 s11]; % 2-by-2-by-K linear complex
s = sparameters(data, freq, 50);Critical: sparameters(data, freq, Z0) expects data as linear complex (not dB). Setting s11 = -20 gives |S11| = 20 (non-physical), not -20 dB. Convert first: 10^(-20/20) = 0.1.
Recipe: Synthetic 4-Port Coupled Channel (No Circuit Construction)
% Port convention: 1,2 near-end; 3,4 far-end
% Through = S31/S42, NEXT = S21/S43, FEXT = S41/S23
freq = linspace(1e9, 20e9, 201)';
delay = 500e-12;
sThru = reshape(10.^(-0.5*(freq/1e9)/20) .* exp(-1j*2*pi*freq*delay), 1, 1, []);
sRefl = reshape(0.05 * ones(size(freq)), 1, 1, []);
sNEXT = reshape(0.02 * exp(-1j*2*pi*freq*delay*0.3), 1, 1, []);
sFEXT = reshape(0.01 * exp(-1j*2*pi*freq*delay*1.2), 1, 1, []);
data = [sRefl sNEXT sThru sFEXT; ...
sNEXT sRefl sFEXT sThru; ...
sThru sFEXT sRefl sNEXT; ...
sFEXT sThru sNEXT sRefl]; % 4-by-4-by-K
s = sparameters(data, freq, 50);Recipe: Lossy Trace with txlineWRLGC (for SI Channel Testing)
freq = linspace(1e6, 20e9, 201)';
tw = txlineWRLGC('Ro', 2, 'Lo', 350e-9, 'Co', 130e-12, 'Go', 0, ...
'Gd', 1e-11, 'LineLength', 0.15, 'Name', 'Trace');
ckt = circuit('channel');
add(ckt, [1 2 0 0], tw);
setports(ckt, [1 0], [2 0]);
s = sparameters(ckt, freq);Gotcha: txlineWRLGC properties are Ro, Lo, Co, Go, Gd -- short forms R, L, G, C error as ambiguous. All txline constructors require name-value pairs (no positional arguments).
Tuning Options
| Option | Default | Purpose |
|---|---|---|
Tolerance | -40 | Target error in dB (recommend -60) |
MaxPoles | 1000 | Upper bound on poles |
Causal | true | Enforce causal (stable) poles |
TendsToZero | true | Force fit to decay to zero as frequency -> infinity |
NoiseFloor | -Inf | Ignore data below this level (dB) |
Qlimit | (finite) | Max pole Q-factor retained; set to inf for filters |
Display | 'off' | Set to 'plot' to visualize fit progress |
Fitting philosophy: A single call to rational with a 'Tolerance' on the tighter side, e.g. -60 (3 digits), is sufficient -- there is no advantage to sweeping multiple tolerance values. The returned errdb indicates the achievable accuracy. If accuracy is insufficient: (1) set 'NoiseFloor' to mask low-level noise, (2) try 'Causal', false as a diagnostic (if accuracy improves significantly, the data has measurement quality issues), or (3) accept the achievable accuracy.
Controlling model order: Use 'MaxPoles' to set a hard upper bound on pole count -- useful when simulator cost scales with poles (e.g., SPICE export). 'Tolerance' is the preferred knob for controlling accuracy, and adjusting 'Tolerance' may or may not affect the number of poles.
TendsToZero: When true (default), the rational model has strictly proper form (numerator order < denominator order), so the response decays to zero at high frequencies. This is appropriate for bandpass or lowpass responses (e.g., insertion loss S21 of a lossy channel, TDT). Set TendsToZero=false for responses that do not vanish at infinity (e.g., reflection coefficients, allpass networks, TDR, or broadband matched loads where S11 plateaus). The false setting produces a more general model with a nonzero direct-feedthrough term (D matrix nonzero).
Qlimit: By default, rational screens out high-Q poles (similar to how it discards unstable poles). This is appropriate for broadband channel data where high-Q poles indicate fitting noise. However, filters and other low-order electrical components have high-Q poles by design. Set 'Qlimit', inf when fitting filter S-parameters to preserve these physically meaningful resonances.
Verification
Two complementary verification approaches:
Approach 1: RF Toolbox Rational Fit Verification
Operates directly on the fit object. Checks the model quality.
% Error metric (returned from rational())
[fit, errdb] = rational(s, 'Tolerance', -60);
fprintf('Poles: %d, Error: %.1f dB, Passive: %d\n', ...
fit.NumPoles, errdb, ispassive(fit));
% Visual: compare fit vs original -- evaluate at intermediate and out-of-band frequencies
% freqresp is inexpensive, so use a dense grid extending beyond the data range
fVerify = linspace(0, 2*s.Frequencies(end), 10001)';
resp = freqresp(fit, fVerify); % Returns N-by-N-by-K for N-port fit
figure; tiledlayout(1,2);
nexttile; plot(s.Frequencies/1e9, 20*log10(abs(rfparam(s,2,1))), '-o', ...
fVerify/1e9, 20*log10(abs(squeeze(resp(2,1,:)))), '--');
xlabel('Frequency (GHz)'); ylabel('|S21| (dB)'); legend('Original','Fit');
nexttile; passivity(fit); % H-inf norm plot (passive where <= 1)This covers complete verification. The errdb + overlay plot + passivity(fit) are the full set of checks needed. Phase plots, pole-zero diagrams, and per-frequency error plots are optional extras -- not required.
passivity(fit) -- Call without arguments for reliable results across releases.
Approach 2: IEEE P370 Quality Check (R2023b+)
Operates on the raw sparameters object. Checks the measurement data quality before fitting.
[cm, rm, pm] = ieee370QualityCheckFrequencyDomain(s);
% cm = causality metric, rm = reciprocity metric, pm = passivity metric
% All return per-frequency vectors. Closer to 0 = better.When to use which:
RF Toolbox (
passivity,errdb): Verify the fit model itself. Always do this.IEEE P370 (
ieee370QualityCheckFrequencyDomain): Verify raw measurement data before fitting. Use when you suspect measurement artifacts (cable flex, calibration drift). Diagnoses whether poor fit accuracy is caused by data quality vs. fitting issues.
Enforce Passivity
if ~ispassive(fit)
fit = makepassive(fit); % Perturbs residues (may reduce accuracy)
fprintf('Post-makepassive error check needed\n');
endmakepassive(fitObj) runs residue optimization -- different from makepassive(sparametersObj) which modifies data point-by-point. Always re-check errdb after calling it.
Extract Poles, Zeros, and State-Space
[z, p, k] = zpk(fit); % Zeros, poles, gain
nPoles = fit.NumPoles; % Number of poles
[A, B, C, D] = abcd(fit); % State-space matricesMulti-Port Cell Array Handling
s = sparameters('channel.s2p');
fit = rational(s);
[yStep, tStep] = stepresp(fit, 1e-11, 10000, 1e-10);
if iscell(yStep)
y21 = yStep{2,1}; % S21 step response
t21 = tStep{2,1}; % Corresponding time vector
else
y21 = yStep; % Single-parameter fit: plain vectors
t21 = tStep;
end
figure; plot(t21*1e9, real(y21));
xlabel('Time (ns)'); ylabel('Amplitude'); title('S21 Step Response (TDT)');Gotcha: For multi-port fits, stepresp, impulse, and timeresp return {N,N} cell arrays for both the response and the time vector. Access element (i,j) as resp{i,j} and t{i,j} -- do not index t as a plain vector. Always verify with iscell(result) before indexing.
Time-Domain Responses
Impulse Response
[yImp, tImp] = impulse(fit21, 1e-12, 5000); % (fit, ts, nPts)Step Response
[yStep, tStep] = stepresp(fit21, 1e-11, 10000, 1e-10); % (fit, Ts_seconds, N_samples, tRise)Arbitrary Waveform via timeresp
u = zeros(1, 5001); u(1) = 1/1e-12; % Impulse input
[yTime, tTime] = timeresp(fit21, u, 1e-12);pwlresp -- Piece-Wise Linear Transient
For periodic or arbitrary piece-wise linear excitation:
tfData = s2tf(s);
fitTF = rational(s.Frequencies, tfData);
sigTime = [0, 0.1, 0.6, 0.7]*1e-9; % Waveform breakpoints
sigValue = [0, 5, 5, 0]; % Values at breakpoints
tPer = 1.5e-9; % Period
tSim = 0:2e-11:3*tPer;
[tran, tPwl] = pwlresp(fitTF, sigTime, sigValue, tSim, tPer);Advanced TDR: pwlresp with Raised Cosine
For better resolution (zero-derivative transitions -- no excitation ringing):
s11 = rfparam(s, 1, 1);
tdrFreqData = (s11 + 1) / 2; % Voltage TDR response in frequency domain
tdrFit = rational(s.Frequencies, tdrFreqData, 'Qlimit', inf, 'TendsToZero', false);
% Raised cosine excitation: bandwidth-limited with zero-derivative transitions
tRise = 1 / s.Frequencies(end); % 20%-80% rise time from measurement bandwidth
Ts = 1e-11;
tSim = (0:10000)' * Ts;
T = 2.44 * tRise; % Full cosine duration (~2.44x rise time)
nRise = ceil(T / Ts);
tPulse = (0:nRise)' * Ts;
pulse = 0.5 * (1 - cos(pi * tPulse / T));
[tdr, tOut] = pwlresp(tdrFit, [tPulse; tSim(end)], [pulse; 1], tSim);
% Convert to impedance profile
s11_recovered = 2*real(tdr) - 1; % Recover reflection coefficient
Z = 50 * (1 + s11_recovered) ./ (1 - s11_recovered); % Impedance in ohmsResolution: TDR spatial resolution is velocity * tRise / 2. With 10 GHz bandwidth and velocity 2e8 m/s, minimum resolvable feature is ~1 cm. Do not interpret ringing artifacts (from limited bandwidth) as physical discontinuities.
Choosing: Rational Fit vs. Direct iFFT
Two approaches exist for computing time-domain responses from frequency-domain data:
| Approach | Best for | Requirements |
|---|---|---|
Rational fit + pwlresp/stepresp/impulse | Reusable model (SPICE export, repeated excitations, pole/zero analysis). Handles non-uniform grids and missing DC natively. | Fitting step (this skill) |
| Direct iFFT with raised cosine pulse | One-shot answer from uniform-grid data. No fitting or model order decisions. Essential for impedance/admittance step responses (Z(f), Y(f)). | Uniform frequency grid + known DC point |
When iFFT cannot be used: The iFFT approach requires a DC point (H(0)). If DC cannot be measured or accurately extrapolated -- common with VNA data that starts at a nonzero frequency -- use rational fitting instead. The rational fit implicitly handles DC extrapolation through its pole/residue model.
Delay Extraction (rationalfit only)
s = sparameters('channel.s2p');
s21 = rfparam(s, 2, 1);
% Use rationalfit (not rational) for delay extraction
fit = rationalfit(s.Frequencies, s21, 'DelayFactor', 1);
fprintf('Channel delay: %.3f ns\n', fit.Delay * 1e9);SPICE and Verilog-A Export
generateSPICE(fit, 'model.sp'); % Export to SPICE subcircuit
writeva(fit, 'model.va', 'in', 'out', 'electrical'); % Verilog-AGotchas
rfwriteblocks on existing files --rfwriteopens an interactive "Overwrite?" dialog if the output file already exists, halting unattended execution. Always pass'ForceOverwrite', trueto suppress the dialog.rationalvsrationalfit-- Userationalfor new code (AAA, converges better). UserationalfitONLY when you need delay extraction ('DelayFactor'option +fit.Delayproperty).Single-param vs multi-port return types --
rational(freq, s21)returns plain vectors fromimpulse/stepresp.rational(sparametersObj)returns{N,N}cell arrays -- access asresp{i,j},t{i,j}.freqresptakes Hz --freqresp(fit, freqInHz)-- NOT rad/s. Passs.Frequenciesdirectly.makepassive(fitObj)can reduce accuracy -- It optimizes residues. Always re-verifyerrdbafter calling it.passivity(fit)-- Call without arguments for reliable results across releases.Poor fit despite tightening Tolerance -- If
errdbplateaus, the raw data has quality issues (non-causal measurement artifacts, noise, insufficient bandwidth). Try'Causal', falseas a diagnostic -- if accuracy improves dramatically, the data is non-causal. Set'NoiseFloor'to mask low-level noise, or accept the achievable accuracy.MaxPolesfor hard upper bounds -- Use when you need to cap pole count (e.g., SPICE export).'Tolerance'is the preferred accuracy knob.Non-causality from cascading S-parameters -- Cascading causal S-parameters can produce non-causal results when frequency spacing is too coarse relative to the electrical length. The "reverse Nyquist criterion": any time-domain feature longer than
1/(2*df)aliases into negative time. If a device has electrical lengthtauwith significant reflections, the effective time-domain duration is2*tau. Cascading N copies givesN*2*tau-- once this exceeds1/(2*df), the cascade becomes non-causal. The fix is finer frequency spacing (smallerdf) before cascading, or accept reduced accuracy in the rational fit ('Causal', falsediagnostic will confirm this mechanism).sparameters(data, freq, Z0)expects linear complex -- Settings11 = -20gives |S11| = 20 (non-physical), not -20 dB. Convert first:10^(-20/20) = 0.1.
Conventions
Use
tiledlayout/nexttilefor multi-panel fit verification figuresAlways label axes with units (GHz, dB, ns) and include figure titles
Plot original and fit data together for visual verification (overlaid on same axes)
Prefer
rational(AAA algorithm) overrationalfit(vector fitting) for new codeUse
'Display', 'off'(default) for unattended runs;'Display', 'plot'for interactive visualization of fit progress
Copyright 2026 The MathWorks, Inc.
Requirements and compatibility
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: Needs Node.js
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-rf · 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-rf.zip