Matlab Model Serdes Systems
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- 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 comprehensive framework for designing and validating Serializer/Deserializer (SerDes) systems. It covers the full development lifecycle, from initial architecture exploration and channel characterization to parameter optimization and the generation of industry-standard IBIS-AMI models. Users can simulate NRZ and PAM-N links, evaluate equalization architectures like FFE, CTLE, and DFE, and perform compliance testing using statistical and time-domain analysis.
What it does
- Models and simulates high-speed serial and parallel links including NRZ and PAM-N signaling.
- Characterizes channels using loss models, S-parameter files, and crosstalk scenarios.
- Optimizes equalization architectures such as FFE, CTLE, and DFE using genetic algorithms.
- Performs statistical and time-domain analysis including eye diagrams and jitter decomposition.
- Exports designs to Simulink for IBIS-AMI model generation and compilation.
- Validates compiled models against behavioral baselines for compliance and performance.
When to use it
- When designing SerDes links for specific data rates and channel loss profiles.
- When evaluating and tuning equalization architectures to meet signal integrity targets.
- When you need to generate IBIS-AMI models for Tx, Rx, Redriver, or Retimer components.
- When performing compliance checks using eye masks and jitter budgets.
- When analyzing captured waveforms from oscilloscopes or simulations.
Advantages
- Full-arc workflow from design exploration to compiled model delivery.
- Supports advanced PAM-N modulation schemes up to PAM16.
- Enables programmatic parameter sweeps and optimization for design space exploration.
- Provides robust validation tools to ensure compiled models match behavioral references.
- Integrates seamlessly with Simulink for complex time-domain system simulations.
Usage examples
- “Create a SerdesSystem object for a PAM4 link and run a statistical analysis.”
- The agent initializes a SerdesSystem with specified Tx/Rx blocks, configures the channel, and executes the analysis() method to generate eye diagrams and performance metrics.
- “Export my current SerDes design to a Simulink model for AMI generation.”
- The agent uses exportToSimulink(sys) to generate the Simulink representation and prepares the IbisAmiManager settings for model compilation.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/matlab/matlab-model-serdes-systems/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-model-serdes-systems.zip -d .agents/skills
Documentation by MathWorks
Modeling and Simulating SerDes Systems
Design, analyze, and deliver high-speed serial link models using SerDes Toolbox. From architecture exploration through IBIS-AMI model generation, covers the full workflow for NRZ and PAM-N links (PAM3 through PAM16).
When to Use
System design and architecture exploration
Designing SerDes links for a target data rate, signaling scheme (NRZ, PAM4, PAM-N), and channel loss
Evaluating equalization architectures (FFE, CTLE, DFE) and optimizing tap settings
Sweeping design parameters to find optimal configurations
Using industry reference designs (PCIe, USB4, DDR5, CEI, UCIe) as starting points
Characterizing Tx/Rx analog effects (parasitic capacitance, rise time, termination impedance)
Building custom datapath blocks for nonstandard equalization
Channel modeling and characterization
Loading S-parameter Touchstone files into SerdesSystem
Modeling channels with loss profiles, crosstalk (FEXT/NEXT), and aggressors
Fitting CTLE transfer functions from measured data via
ctlefit
IBIS-AMI model generation
Building IBIS-AMI models for Tx, Rx, Redriver, or Retimer configurations
Exporting to Simulink, configuring AMI parameters, and compiling
.ami/.ibs/.dll/.soScripting Simulink simulations and parameter sweeps with
sim/parsim
Analysis and validation
Running statistical and time-domain simulations
Processing eye diagrams (eye height, eye width, COM, VEC, bathtub curves)
Decomposing jitter (TJ, RJ, DJ, DDJ, DCD, ISI)
Validating compiled AMI models against behavioral baselines
Running compliance checks with eye masks and jitter budgets
When NOT to Use
RF/microwave circuit design, antenna modeling, or baseband DSP filter design
General Simulink model scripting unrelated to SerDes
Must-Follow Rules
System Setup
SymbolTime / SampleInterval must yield an integer SamplesPerSymbol — fractional ratios cause silent errors
TxModel/RxModelareTransmitter/Receiverobjects — not cell arrays. Construct withTransmitter('Blocks', {block1, block2}).Transmitterrequires single-quoted property names —Transmitter("Blocks", ...)throws anismembererror.Receiverand all other classes accept double quotesSignal conversion functions require column vectors —
impulse2pulse,pulse2stateye, etc. error on row vectorsInclude
AnalogModelandJitterAndNoisefor realistic results — bareTransmitter/Receiverwithout analog models produce optimistic COM (1-2 dB higher). Seereference/equalization-tuning.mdfor parameter guidance (rise time, parasitic C, termination R)
Equalization
Set
WaveTypeexplicitly when using datapath blocks directly in MATLAB — Simulink sets this automatically, but MATLAB defaults to"Sample"Adapted DFE/CTLE parameters are in
results.outparams— NOT on the block object. Afteranalysis(),sys.RxModel.Blocks{k}.TapWeightsstill holds initial values. In system objects chains, adapted taps are the second output:[y, taps] = dfecdr(x)DFECDR Mode=0 is passthrough in Sample mode — DFE only applies with Mode≥1. Pre-load adapted taps from
outparamswith Mode=1 for instant convergence, or use Mode=2 with 10xEqualizationGain(9.6e-04) for self-converging chainsSet
Modulationon DFECDR for PAM-N in system objects chains — Simulink inherits it from the model workspace, but MATLAB defaults to 2 (NRZ). Without this, PAM4 DFE adaptation fails silently
Metrics and Waveforms
Metrics.summary.EWis in picoseconds (already scaled) — do NOT multiply by 1e12.EHis in volts. PAM-N returns N-1 values per metric (e.g., PAM4 → 3 eyes, PAM8 → 7 eyes)Channel impulse from
analysis()is in V/s — when usingfilter()for time-domain convolution, multiply bydt:filter(impulse * dt, 1, wave). Without scaling, amplitudes blow up by ~10^11pulse2waveoperates on the stimulus provided — the output modulation depends on the input pattern (NRZ or PAM-N)
AMI and Simulink
Init-Only models cannot adapt — if DFE taps or CDR converge at runtime, you need a Dual model (both Init and GetWave)
AMI validation requires Signal Integrity Toolbox —
serdes.AMIrunner and the AMI Simulink block need both SerDes Toolbox and Signal Integrity ToolboxAMI GetWave: call in a chunked loop —
serdes.AMIpassesBlockSize(default 1024) toAMI_GetWave, so onlyBlockSizesamples are processed per call. You must call the object in aforloop withBlockSize-length chunks. State is preserved between calls via the DLL memory handleAMI GetWave: set
SkipFirstBlock = falsewhen calling from MATLAB — the default (true) is for Simulink's internal signal buffering and causes the first block to pass through unprocessedAMI Init:
RowSizemust match impulse length —serdes.AMIcrashes MATLAB (process termination, no error) ifRowSizedoesn't matchnumel(impulse)AMI generation requires Simulink model — use
IbisAmiManagerGUI orserdes.AMIExportwithexport()programmatically (see Programmatic AMI Generation)
Workflow
Design Exploration
Most projects start here. The goal is to find the right equalization architecture and settings for your channel.
Design — Create a
SerdesSystemwith Tx/Rx blocks and channel (loss model or S-parameters)Analyze — Run
analysisfor statistical results,plotStatEyefor eye diagrams,analysisReportfor metricsSweep — Vary channel loss, FFE taps, CTLE gain, DFE taps, or jitter to map the design space
Compare — Evaluate architectures (FFE-only vs FFE+CTLE vs FFE+CTLE+DFE) using COM, eye height, eye width
Select — Choose the configuration that meets margin targets, then freeze equalization settings
Use SerdesSystem for programmatic exploration; serdesDesigner for interactive GUI work.
Waveform Processing
When you have a captured or imported waveform (e.g., from an oscilloscope or simulation) and want to equalize and analyze it directly:
Load — Import the waveform and define timing (
SampleInterval,SymbolTime)Equalize — Stream through datapath blocks (FFE, CTLE, DFECDR) with
WaveType = "Sample"Analyze — Build an eye diagram with
eyeDiagramSI, extract metrics (eye height, COM, VEC)Decompose jitter — Run
jitter()on the equalized waveform for TJ, RJ, DJ, DDJ, ISI breakdown
DFECDR and DFE require a sample-by-sample for loop in Sample mode; FFE and CTLE accept full vectors. See reference/waveform-processing.md for the Direct Equalization pattern.
IBIS-AMI Model Delivery
When you need compiled models (.ami/.ibs/.dll/.so) for EDA tools or IP delivery:
Export — Call
exportToSimulink(sys)to generate a Simulink model from the frozen designConfigure — Set AMI parameters, IBIS component/pin data, and model type via
IbisAmiManagerorserdes.AMIExportGenerate — Build
.ami/.ibsand compile.dll/.soviaserdes.AMIExportwithexport()Validate — Load compiled DLL/SO with
serdes.AMI, compare against behavioral reference (Init for impulse, GetWave for waveform)Cross-check — The Simulink path (
simwith Rx WaveOut) is the preferred time-domain reference. Compare against: statisticalanalysis(), system objects direct chain, and compiled AMI DLLs. Seereference/simulink-serdes-simulation.mdIterate — Fix discrepancies, re-export, re-validate until all paths agree
AMI Model Types
Choose the model type based on which equalization blocks need to adapt at runtime:
| Type | Init_Returns_Impulse | GetWave_Exists | Use For |
|---|---|---|---|
| Init-Only | true | false | LTI equalization (fixed FFE, CTLE). Supports statistical analysis |
| GetWave-Only | false | true | Time-domain only. No statistical analysis |
| Dual | true | true | Adaptive equalization (DFE, CDR). All analysis types |
Every IBIS-AMI model implements AMI_Init (required), AMI_GetWave (optional), and AMI_Close (required) per the IBIS standard.
Key Classes
| Class | Purpose |
|---|---|
SerdesSystem | Top-level system. Methods: analysis, plotStatEye, plotImpulse, plotPulse, plotAlignedPulse, plotWavePattern, analysisReport, exportToSimulink |
Transmitter | Tx container. Construct: Transmitter('Blocks', {serdes.FFE(...)}) |
Receiver | Rx container. Construct: Receiver('Blocks', {serdes.CTLE(...), serdes.DFECDR(...)}) |
ChannelData | Channel spec. Props: ChannelLossdB, ChannelLossFreq (default 5 GHz — must override to Nyquist), ChannelDifferentialImpedance, or Impulse/dt |
JitterAndNoise | IBIS 7.0 jitter/noise. 4 groups: Tx jitter (Rj/Dj/DCD/Sj), Rx jitter, Rx clock recovery (5 params, active with RxClockMode='clocked', 'convolved', or 'normal'), Rx noise. Values in seconds (default) or UI. See reference/serdes-api-reference.md |
serdes.AMI | Run compiled AMI DLLs/SOs. Call: [waveOut, impulseOut] = ami(waveIn, impulseIn, clockIn) |
serdes.AMIExport | Programmatic AMI export (R2026a+). Methods: export, getExportSettings. Props: ModelTypeTx, DLLFiles, LinuxCrossCompile |
SParameterChannel | S-parameter to impulse response. Handles .s4p through .s16p (multi-port returns Nx(K) matrix: col 1=thru, cols 2+=aggressors). Props: FileName, SampleInterval, StopTime, PortOrder |
eyeDiagramSI | Waveform eye diagram (R2024a+). Step: eyeObj(wave) — no output. Metrics: eyeHeight, eyeWidth, com, vec, margin |
ctlefit | CTLE pole/zero fitter. Import: ctlefit.readcsv. Output: GPZ matrix for serdes.CTLE("Specification", "GPZ Matrix") |
Datapath Blocks
| Block | Role | Mode Values | Key Properties |
|---|---|---|---|
serdes.FFE | Feed-forward equalizer | 0, 1 | TapWeights, TapSpacing, Normalize |
serdes.CTLE | Continuous-time linear EQ | 0, 1, 2 | Specification, DCGain, ACGain, PeakingGain, GPZ |
serdes.DFECDR | DFE + clock recovery | 0, 1, 2 | TapWeights, CDRMode, PhaseDetector, Count |
serdes.DFE | Standalone DFE | 0, 1, 2 | TapWeights, EqualizationGain, EqualizationStep |
serdes.CDR | Standalone CDR | 0, 1 | CDRMode, Count, Step, Sensitivity. Mode is deprecated |
serdes.AGC | Auto gain control | 0, 1 | TargetRMSVoltage, MaxGain, AveragingLength |
serdes.VGA | Variable gain amplifier | 0, 1 | Gain |
serdes.SaturatingAmplifier | Limiting amplifier | 0, 1 | Limit, LinearGain, Specification |
serdes.PassThrough | No-op placeholder | — | — |
Mode values: 0 = Fixed (not exported), 1 = Fixed (exported as AMI parameter), 2 = Adaptive (GetWave). Only CTLE, DFECDR, and DFE support Mode=2.
Set CTLE Specification before setting gain properties — using ACGain with the default spec triggers a warning. GPZ Matrix requires Mode=1 for ConfigSelect to switch rows. See reference/equalization-tuning.md for the 4 specification options.
Patterns
Each reference file includes executable code patterns for its topic. Load the relevant reference before writing code — it contains correct calling conventions, constructor arguments, and property names. See the References table in Conventions below for the full routing map.
Common Mistakes
See reference/common-mistakes.md for 37 documented anti-patterns with wrong/correct code pairs covering API misuse, wrong property names, silent failures, and performance pitfalls.
Conventions
Design
Use
SerdesSystemfor programmatic design;serdesDesignerfor interactive exploration. Always runanalysis/plotStatEyebefore exportingCRITICAL:
ChannelLossFreqdefaults to 5 GHz — always override to Nyquist (1/(2*SymbolTime)). Without this, 15 dB at 5 GHz becomes 40+ dB at Nyquist and the eye appears closed. UseSParameterChannelfor real channelsanalysis()does not auto-optimize FFE taps — use canonical de-emphasis withsum(abs(taps)) ≈ 1.0DFE taps initialized to zero are optimized by the statistical solver automatically
Industry reference designs:
serdesDesigneroropenExample('serdes/PCIe5TransmitterReceiverIBISAMIModelExample'). Seereference/equalization-tuning.mdfor starting-point configurations
Visualization and Metrics
All
SerdesSystemplot methods (plotStatEye,plotImpulse,plotPulse,plotAlignedPulse,plotWavePattern) render into the current axes — usetiledlayout/nexttileorsubplotfor multi-panel layoutseyeDiagramSI(R2024a+) for waveform eye diagrams;jitter(R2024b+) for jitter decompositionDFECDR/DFE in
"Sample"WaveType require scalar (sample-by-sample) input; FFE/CTLE accept full vectorsWhen generating PRBS waveforms via
pulse2wave, ask the user for PRBS order and symbol count — default PRBS-10 (1023 symbols) if unspecifiedUse
serdes.utilities.SignalIntegrityColorMap(nothot/parula) forpulse2stateyeplots. For compliance, usemargin(eyeObj, eyeMask)See
reference/visualization-and-metrics.mdfor all plot methods, metrics fields/units, eyeDiagramSI, and jitter
AMI Export and Validation
Use
serdes.AMIExportwithexport()for programmatic AMI generation — notslbuild(legacy, R2025b and earlier only)Validate compiled DLLs/SOs with
serdes.AMIbefore sending to EDA tools — both Init (impulse correlation) and GetWave (waveform chain)Simulink is the preferred time-domain path —
sim()with Rx WaveOut is the ground truth for adaptive systems. Compare against system objects chain and compiled AMI DLLs as cross-checks. Use the same PRBS stimulus across all time-domain pathsAMI export parameters on Simulink blocks use
*AMIsuffix ('ModeAMI','TapWeightsAMI'); model-level settings go throughIbisAmiManagerorserdes.AMIExportNo compiled DLLs/SOs ship with the toolbox. Cross-compile for Linux
.soviaserdes.utilities.createCrossCompiler
Script-First Workflow
For design, analysis, or sweep tasks — write code to .m files on disk, not inline MCP snippets. For quick one-off checks, inline evaluate_matlab_code is fine.
Create a
.mfile (e.g.,serdes_pam4_design.m), run viarun_matlab_file, iterate by editing and re-runningDeliver a polished script —
%% Parametersblock at top,%% Sectionheaders, summaryfprintfat end
References
| Load when... | Reference |
|---|---|
Building or modifying a SerdesSystem | reference/serdes-api-reference.md |
| Debugging wrong API names or silent failures | reference/common-mistakes.md |
| Working with S-parameter files or crosstalk | reference/channel-modeling.md |
| Tuning CTLE, FFE, DFE, or fitting transfer functions | reference/equalization-tuning.md |
| Sweeping parameters or running GA optimization | reference/optimization.md |
| Plotting eyes, reading metrics, or decomposing jitter | reference/visualization-and-metrics.md |
| Equalizing captured or imported waveforms directly | reference/waveform-processing.md |
| Exporting to Simulink, compiling AMI DLLs, or validating AMI models | reference/programmatic-ami-generation.md |
Scripting Simulink simulations or parsim sweeps | reference/simulink-serdes-simulation.md |
| Building custom datapath blocks | reference/custom-datapath-blocks.md |
| Looking up utility functions (SNR, ICN, resample) | reference/serdes-utilities.md |
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md16.4 KiB
- manifest.yaml1000 B
- reference/channel-modeling.md7.8 KiB
- reference/common-mistakes.md28.5 KiB
- reference/custom-datapath-blocks.md12.8 KiB
- reference/equalization-tuning.md11.4 KiB
- reference/optimization.md9.0 KiB
- reference/programmatic-ami-generation.md25.4 KiB
- reference/serdes-api-reference.md28.4 KiB
- reference/serdes-utilities.md10.4 KiB
- reference/simulink-serdes-simulation.md19.4 KiB
- reference/visualization-and-metrics.md20.0 KiB
- reference/waveform-processing.md7.8 KiB
reference/simulink-serdes-simulation.md
Simulink SerDes Simulation Scripting
Run SerDes Simulink models programmatically with sim(), sweep parameters
with parsim, configure blocks with set_param/get_param, and correlate
behavioral models against third-party IBIS-AMI DLLs using the AMI block.
When to Use sim() vs analysis()
| Criterion | analysis(sys) | sim(mdl) |
|---|---|---|
| Domain | Statistical (Init path) | Time-domain (GetWave path) |
| Speed | Fast (~1 s) | Slow (~10-60 s per run) |
| DFE adaptation | Optimized but not converged | Fully converged per-sample |
| CDR convergence | Not modeled | Full bang-bang/baud-rate |
| Waveform output | Synthetic from pulse | Actual sample-by-sample |
| Third-party DLL | Not supported | Supported via AMI block |
| Parameter sweep | Loop over analysis() | parsim with SimulationInput |
Simulink sim() is the preferred time-domain approach — it is the ground
truth for adaptive systems. Use it for: DFE/CDR adaptation, waveform-level
debugging, AMI DLL correlation, or access to per-sample signal logging.
System objects chains and AMI DLL chains serve as cross-checks against Simulink.
Model Structure After exportToSimulink
After exportToSimulink(sys), the Simulink model contains:
mdl/
├── Tx/
│ ├── FFE % serdes.FFE block
│ ├── VGA % (if present)
│ └── SaturatingAmplifier % (if present)
├── Analog Channel/ % serdes.ChannelLoss or ChannelImpulse
├── Rx/
│ ├── CTLE % serdes.CTLE block
│ ├── DFECDR % serdes.DFECDR block
│ └── AGC % (if present)
├── Configuration % SerDes system parameters + IbisAmiManager
└── Stimulus % serdes.Stimulus blockBlock paths follow the pattern [mdl '/Tx/FFE'], [mdl '/Rx/CTLE'], etc.
Model Workspace
The model workspace contains Simulink.Signal objects (not plain doubles):
| Variable | Type | Description |
|---|---|---|
SymbolTime | Simulink.Signal | Symbol period (s) |
SampleInterval | Simulink.Signal | Sample interval (s) |
TargetBER | Simulink.Signal | Target bit error rate |
Modulation | Simulink.Signal | Number of levels (2, 4, ...) |
Access:
mdlWks = get_param(mdl, 'ModelWorkspace');
symTime = mdlWks.getVariable('SymbolTime');
% symTime is a Simulink.Signal — read .InitialValue for the numeric valueRunning sim()
% 1. Export and open model
exportToSimulink(sys);
mdl = "mySerDesModel"; % model name from exportToSimulink
% 2. Configure simulation
set_param(mdl, 'StopTime', '5e-8'); % 50 ns
% 3. Run simulation
out = sim(mdl);
% 4. Extract logged signals from SimulationOutput
% Signal logging depends on model configuration.
% Access via out.logsout if signal logging is enabled:
% logsout = out.logsout;
% txOut = logsout.getElement('TxOut').Values;Critical: sim() returns a Simulink.SimulationOutput object, not
workspace variables. Access results through the output object's fields.
set_param / get_param
All parameter values in set_param are strings — use num2str or
mat2str to convert numeric values.
Common SerDes Block Parameters
% FFE tap weights
set_param([mdl '/Tx/FFE'], 'TapWeights', mat2str([-0.1 0.7 -0.2]));
% CTLE gain (depends on Specification)
set_param([mdl '/Rx/CTLE'], 'ACGain', num2str(12));
set_param([mdl '/Rx/CTLE'], 'DCGain', num2str(0));
% DFECDR tap weights
set_param([mdl '/Rx/DFECDR'], 'TapWeights', mat2str(zeros(1, 10)));
% Channel loss
set_param([mdl '/Analog Channel'], 'Loss', num2str(15));
set_param([mdl '/Analog Channel'], 'TargetFrequency', num2str(14e9));
% Read current values
currentTaps = get_param([mdl '/Tx/FFE'], 'TapWeights'); % returns char
tapValues = str2num(currentTaps); %#ok<ST2NM> — needed for mat2str'd arraysStimulus Configuration
The Stimulus block mask uses so prefix for parameters (e.g., soSpecification
instead of Specification). Jitter units default to UI — override with so*Unit params.
set_param([mdl '/Stimulus'], 'soSpecification', 'Serial PRBS');
set_param([mdl '/Stimulus'], 'soOrder', '11');
set_param([mdl '/Stimulus'], 'soRjUnit', 'Seconds'); % default is UI — must override
set_param([mdl '/Stimulus'], 'soRj', '1e-12'); % 1 ps RMS random jitter
set_param([mdl '/Stimulus'], 'soDjUnit', 'Seconds');
set_param([mdl '/Stimulus'], 'soDj', '3e-12'); % 3 ps deterministic jitterparsim Parameter Sweeps
Use Simulink.SimulationInput arrays for parallel or sequential sweeps.
% Sweep CTLE AC gain from 0 to 20 dB
acGainValues = 0:2:20;
N = numel(acGainValues);
% Build SimulationInput array
simIn(1:N) = Simulink.SimulationInput(mdl);
for k = 1:N
simIn(k) = simIn(k).setBlockParameter(...
[mdl '/Rx/CTLE'], 'ACGain', num2str(acGainValues(k)));
end
% CRITICAL: save model before parsim
save_system(mdl);
% Run sweep (sequential by default; use 'UseFastRestart', 'on' for speed)
out = parsim(simIn, 'ShowProgress', 'on', 'UseFastRestart', 'on');
% Extract results from each run
for k = 1:N
% Access simulation output for run k
simOut = out(k);
% Process results...
endMulti-Parameter Sweep
% 2D sweep: FFE taps × channel loss
ffeTapSets = {[-0.05 0.9 -0.05], [-0.1 0.8 -0.1], [-0.15 0.7 -0.15]};
lossValues = [8, 12, 16, 20];
idx = 0;
for i = 1:numel(ffeTapSets)
for j = 1:numel(lossValues)
idx = idx + 1;
simIn(idx) = Simulink.SimulationInput(mdl);
simIn(idx) = simIn(idx).setBlockParameter(...
[mdl '/Tx/FFE'], 'TapWeights', mat2str(ffeTapSets{i}), ...
[mdl '/Analog Channel'], 'Loss', num2str(lossValues(j)));
end
end
save_system(mdl);
out = parsim(simIn, 'ShowProgress', 'on');Simulink SerDes Block Reference
serdes.Stimulus
PRBS pattern generator with jitter injection.
| Property | Default | Description |
|---|---|---|
Specification | "Random Symbols" | Pattern type (10 options — see below) |
Modulation | 2 | Symbol levels: 2 (NRZ) to 32 |
Order | 7 | PRBS order (scalar or vector for parallel) |
Seed | {[0 1 0 1 0 1 0]} | PRBS seed (cell of binary vectors) |
Dj | 0 | Deterministic jitter |
Rj | 0 | Random jitter (std dev) |
DCD | 0 | Duty cycle distortion |
Sj | 0 | Sinusoidal jitter |
SjFrequency | 0 | Sj frequency (Hz) |
BinaryToPAMnMapping | "Default" | Mapping: "Default", "ETH_100BASE_T1", "USB4V2", "Uniform" |
SymbolTime | 100e-12 | Symbol period (s) |
SampleInterval | 6.25e-12 | Sample interval (s) |
Specification options: "Random Symbols", "Symbol Pattern",
"Serial PRBS", "Binary Pattern", "Symbol Voltage Pattern",
"Sampled Voltage", "Parallel PRBS", "PRBS", "PAMn", "Data Pattern"
Jitter units default to UI (not Seconds). Set soRjUnit/soDjUnit/soDCDUnit/soSjUnit
to 'Seconds' for absolute values. Passing seconds values without overriding the unit
silently treats them as UI fractions (e.g., 1e-12 UI ≈ zero jitter).
serdes.ChannelLoss
Simple lossy transmission line model (IEEE 802.3bj-2014).
| Property | Default | Description |
|---|---|---|
Loss | 8 | Channel power loss at target frequency (dB) |
TargetFrequency | 10e9 | Frequency for specified loss (Hz) |
dt | 1e-12 | Sample interval (s) |
Zc | 100 | Differential characteristic impedance (ohms) |
TxR / RxR | 50 | Single-ended Tx/Rx impedance (ohms) |
TxC / RxC | 1e-12 | Single-ended Tx/Rx capacitance (F) |
RiseTime | 10e-12 | 20-80% rise time of stimulus (s) |
VoltageSwingIdeal | 1 | Vpp at Tx analog model input (V) |
EnableCrosstalk | false | Include crosstalk in simulation |
CrosstalkSpecification | "CEI-28G-SR" | Spec: "CEI-25G-LR", "CEI-28G-VSR", "100GBASE-CR4", "Custom" |
FEXTICN / NEXTICN | 15e-3 / 10e-3 | Desired ICN levels (V RMS) |
serdes.ChannelImpulse
Channel modeled by user-provided impulse response(s).
| Property | Default | Description |
|---|---|---|
ImpulseMatrix | — | Column matrix of impulse responses (Nx1 or Nx2xM for crosstalk) |
SampleInterval | — | Time step of impulse responses (s) |
For multi-lane with crosstalk, the step method accepts multiple scalar inputs (one per lane) and returns multiple outputs:
convImp = serdes.ChannelImpulse('ImpulseMatrix', imp, 'SampleInterval', dt);
[yThru, yFext, yNext] = convImp(stimMain, stimFext, stimNext);serdes.EyeAnalyzer
Waveform-based eye diagram analyzer. MATLAB-only — do not add to Simulink.
| Property | Default | Description |
|---|---|---|
SymbolTime | — | Symbol period (s) |
SampleInterval | — | Sample interval (s) |
ClockMode | "Clocked" | "Clocked", "Ideal", "Convolved" |
IgnoreSymbols | 0 | Skip initial symbols (CDR convergence) |
Dj/Rj/DCD/Sj | 0 | Receiver jitter impairments |
GaussianNoise | 0 | Additive Gaussian noise std dev (V) |
UniformNoise | 0 | Additive uniform noise half-Vpp (V) |
ReceiverSensitivity | 0 | Metastability voltage (V) |
ClockIsInput | false | Set true when providing clock waveform |
ThresholdIsInput | false | Set true when providing threshold waveform |
Read-only outputs: EyeHistogram, EyeTime, EyeVoltage, ClockPDF
Usage with CDR clock:
ea = serdes.EyeAnalyzer('SymbolTime', symbolTime, 'SampleInterval', dt, ...
'ClockIsInput', true, 'IgnoreSymbols', ignoreSymbols);
ea(waveIn, clockTimes, clockValidOnRising);
% Visualize
cmap = serdes.utilities.SignalIntegrityColorMap;
figure; imagesc(ea.EyeTime, ea.EyeVoltage, ea.EyeHistogram);
axis xy; colormap(cmap); colorbar;Rx WaveOut Port and Time-Domain Capture
The Rx subsystem's WaveOut port provides the fully equalized output waveform —
after FFE, CTLE, DFE, and CDR have all processed the signal. This is the same
signal that feeds the Simulink Eye Diagram block.
To capture this waveform programmatically for external analysis (e.g., eyeDiagramSI):
Enable signal logging on the Rx
WaveOutport (or useout.youtif configured)Run
sim(mdl)and extract from theSimulationOutputobjectFeed the extracted waveform into
eyeDiagramSIfor independent metrics
Simulink Results Viewer: Statistical vs Time-Domain
The Simulink SerDes model's built-in results viewer reports both statistical
and time-domain metrics. The statistical results use the same pulse-based
engine as analysis(sys), so they should be numerically identical to
sys.Metrics.summary. The time-domain results come from the actual simulation.
This gives a natural cross-check: if the Simulink statistical results differ from
analysis(sys), the model export or configuration has diverged.
AMI Block for Third-Party DLL Correlation
Two paths for using vendor IBIS-AMI DLLs:
| Path | Tool | Use case |
|---|---|---|
| Simulink integration | AMI Tx/Rx blocks in SerDes testbench | Full time-domain simulation with vendor DLLs inside the Simulink model. Import vendor .ami/.ibs/.dll files into the Configuration block via IbisAmiManager. |
| Standalone validation | serdes.AMI system object in MATLAB | Quick Init/GetWave correlation outside Simulink. Compare vendor DLL output against behavioral reference. |
For Simulink integration, use exportToSimulink(sys) to create the testbench, then open the Configuration block and load vendor AMI files via IbisAmiManager. For standalone validation, use serdes.AMI as shown below.
serdes.AMI Configuration
ami = serdes.AMI;
ami.LibraryName = "vendor_tx"; % DLL filename without extension
ami.LibraryPath = fullfile(pwd, "dlls"); % directory containing .dll/.so
ami.SymbolTime = symbolTime;
ami.SampleInterval = dt;
ami.RowSize = N; % must match numel(impulse)
ami.BlockSize = 1024; % samples per GetWave call (default)
ami.InitOnly = false; % true = Init only, false = Init + GetWave
ami.SkipFirstBlock = false; % set false when calling from MATLAB
ami.InputString = "(vendor_tx)"; % root name from .ami fileImportant: When InitOnly = false, call the object in a for loop with
BlockSize-length chunks — AMI_GetWave processes exactly BlockSize samples
per call. The DLL state persists between calls. See reference/serdes-api-reference.md
for the chunked loop pattern.
Generating InputString for Third-Party .ami Files
% Parse .ami file and generate default parameter string
inputStr = serdes.AMI.generateDefaultInputString("vendor_model.ami");
ami.InputString = inputStr;AMI Correlation Workflow
% 1. Design behavioral model
sys = SerdesSystem(...);
results = analysis(sys);
channelImpulse = results.impulse(:, 1); % unequalized
simReference = results.impulse(:, 2); % equalized (behavioral)
N = numel(channelImpulse);
% 2. Run Tx DLL Init — LibraryName is DLL filename without .dll extension
exportDir = fullfile(pwd, "export");
txAmi = serdes.AMI;
txAmi.LibraryName = "serdes_tx_win64"; % from export(): serdes_tx_win64.dll
txAmi.LibraryPath = exportDir;
txAmi.SymbolTime = sys.SymbolTime;
txAmi.SampleInterval = sys.dt;
txAmi.InitOnly = true;
txAmi.InputString = "(serdes_tx)"; % root name from .ami file
txAmi.RowSize = N;
[~, txOut] = txAmi(zeros(N, 1), channelImpulse, -1);
% 3. Run Rx DLL Init
rxAmi = serdes.AMI;
rxAmi.LibraryName = "serdes_rx_win64";
rxAmi.LibraryPath = exportDir;
rxAmi.SymbolTime = sys.SymbolTime;
rxAmi.SampleInterval = sys.dt;
rxAmi.InitOnly = true;
rxAmi.InputString = "(serdes_rx)";
rxAmi.RowSize = N;
[~, rxOut] = rxAmi(zeros(N, 1), txOut, -1);
% 4. Compare
corrCoef = corrcoef(simReference, rxOut);
fprintf("Correlation: %.6f\n", corrCoef(1, 2)); % expect ≈ 1.0GetWave validation — sample-for-sample comparison against Simulink:
Log the channel output from Simulink and feed the exact same waveform to the DLL in a chunked loop. This achieves perfect correlation (max diff at machine epsilon).
Note: rxOut is logged by default after exportToSimulink. The channel output
(chOut) is not — you must manually enable signal logging on the Analog Channel
output port and name it chOut.
% 1. Run Simulink to get ground truth
simOut = sim(mdl);
chSimWave = simOut.logsout.get('chOut').Values.Data(:); % manual logging required
rxSimWave = simOut.logsout.get('rxOut').Values.Data(:); % logged by default
% 2. Run Rx DLL in chunked loop
blockSize = 1024;
rxAmiGW = serdes.AMI;
rxAmiGW.LibraryName = "serdes_rx_win64"; rxAmiGW.LibraryPath = exportDir;
rxAmiGW.SymbolTime = sys.SymbolTime; rxAmiGW.SampleInterval = sys.dt;
rxAmiGW.InitOnly = false; rxAmiGW.SkipFirstBlock = false;
rxAmiGW.RowSize = N; rxAmiGW.BlockSize = blockSize;
rxAmiGW.InputString = "(serdes_rx)";
Nsim = numel(chSimWave);
nPad = ceil(Nsim / blockSize) * blockSize;
wavePad = [chSimWave; zeros(nPad - Nsim, 1)];
waveOut = zeros(nPad, 1);
clockIn = -ones(blockSize, 1);
for k = 1:nPad/blockSize
idx = (k-1)*blockSize + (1:blockSize);
[waveOut(idx), ~] = rxAmiGW(wavePad(idx), channelImpulse, clockIn);
end
dllWave = waveOut(1:Nsim);
% 3. Compare — expect correlation = 1.0 and max diff ≈ 1e-15
R = corrcoef(rxSimWave, dllWave);
fprintf("GetWave vs Simulink: corr=%.15f, max diff=%.2e\n", R(1,2), max(abs(rxSimWave - dllWave)));AMI Data Output (Simulink AMI Block)
When using the AMI block in a Simulink model, the AMIData output port
provides a struct with:
| Field | Description |
|---|---|
ImpulseIn | Input impulse response (before AMI processing) |
ImpulseOut | Output impulse response (after AMI Init) |
AMIMessages | String messages from AMI_Init/AMI_GetWave |
InitStatus | AMI_Init return status |
GetWaveStatus | AMI_GetWave return status |
ClockTimesIn | Input clock times |
ClockTimesOut | Output clock times (after CDR) |
CloseStatus | AMI_Close return status |
InitPassThrough for Baseline Comparison
The AMI block's InitPassThrough checkbox runs only AMI_Init (skipping
GetWave), providing a behavioral baseline for comparison:
Run with
InitPassThrough = true→ captures Init-only impulseRun with
InitPassThrough = false→ captures full Init + GetWaveCompare impulse responses to verify GetWave contribution
Complete Scripted Workflow
%% 1. Design
sys = SerdesSystem(...
'TxModel', Transmitter('Blocks', {serdes.FFE('TapWeights', [-0.1 0.7 -0.2])}), ...
'RxModel', Receiver('Blocks', {serdes.CTLE('Specification', "DC Gain and AC Gain", ...
'DCGain', 0, 'ACGain', 10), serdes.DFECDR('TapWeights', zeros(1, 5))}), ...
'SymbolTime', 35.71e-12, 'SamplesPerSymbol', 16, 'Modulation', 4);
sys.ChannelData.ChannelLossdB = 15;
%% 2. Statistical baseline
results = analysis(sys);
fprintf("Statistical COM: %.1f dB\n", sys.Metrics.summary.COMestimate);
%% 3. Export to Simulink
exportToSimulink(sys);
mdl = "mySerDesModel";
%% 4. Configure and simulate
set_param(mdl, 'StopTime', '1e-7');
out = sim(mdl);
%% 5. Sweep CTLE gain
acGains = 0:4:20;
simIn(1:numel(acGains)) = Simulink.SimulationInput(mdl);
for k = 1:numel(acGains)
simIn(k) = simIn(k).setBlockParameter(...
[mdl '/Rx/CTLE'], 'ACGain', num2str(acGains(k)));
end
save_system(mdl);
sweepOut = parsim(simIn, 'UseFastRestart', 'on');Common Mistakes
1. save_system Required Before parsim
% WRONG — model not saved, parsim may use stale parameters
out = parsim(simIn);
% CORRECT — always save before parsim
save_system(mdl);
out = parsim(simIn);2. Block Parameter Values Must Be Strings
% WRONG — numeric value
set_param([mdl '/Rx/CTLE'], 'ACGain', 12); % ERROR
% CORRECT — string value
set_param([mdl '/Rx/CTLE'], 'ACGain', num2str(12));
set_param([mdl '/Tx/FFE'], 'TapWeights', mat2str([-0.1 0.8 -0.1]));3. Model Workspace whos Uses Lowercase Fields
% WRONG — uppercase field names
mdlWks = get_param(mdl, 'ModelWorkspace');
varNames = {mdlWks.whos.Name}; % ERROR: Unrecognized field
% CORRECT — lowercase field names (name, class, size, bytes)
varNames = {mdlWks.whos.name};
varClasses = {mdlWks.whos.class};4. sim() Returns SimulationOutput, Not Variables
% WRONG — expecting workspace variables
out = sim(mdl);
wave = out.TxWave; % May not exist as a direct field
% CORRECT — use logsout for logged signals
out = sim(mdl);
if ~isempty(out.logsout)
txSig = out.logsout.getElement('TxOut').Values;
end5. EyeAnalyzer Is MATLAB-Only
% WRONG — adding to Simulink model
% serdes.EyeAnalyzer cannot be used as a Simulink block
% CORRECT — use in MATLAB post-processing after sim()
ea = serdes.EyeAnalyzer('SymbolTime', symbolTime, 'SampleInterval', dt);
ea(extractedWaveform); % process waveform extracted from sim output6. AMI LibraryName and InputString
% WRONG — LibraryName must be the DLL filename (without .dll), not the .ami root
ami.LibraryName = "serdes_tx"; % ERROR: no file serdes_tx.dll
ami.InputString = "(myModel_tx)"; % ERROR: root name mismatch with .ami
% CORRECT — LibraryName = DLL filename; InputString root = .ami file root
ami.LibraryName = "serdes_tx_win64"; % matches serdes_tx_win64.dll
ami.InputString = "(serdes_tx)"; % matches root in serdes_tx.ami
% Or use generateDefaultInputString to parse from .ami fileCopyright 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.
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-serdes-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.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-model-serdes-systems.zip