Generated banner for Matlab Model Serdes Systems
Generated logo for Matlab Model Serdes Systems

Matlab Model Serdes Systems

MathWorksOfficialCreated by MathWorks

  • Skill
  • Tool integration
  • Science and research
  • BSD-2-Clause
  • No issues found

From the author

Model, simulate, and optimize Serializer/Deserializer (SerDes) systems — serial and parallel links — using MATLAB SerDes Toolbox. Design NRZ and PAM-N links (PAM3 through PAM16) — explore equalization architectures (FFE, CTLE, DFE), sweep or optimize parameters with genetic algorithms, and characterize channels from loss models, S-parameter files, or crosstalk scenarios. Process captured waveforms through equalization chains, build eye diagrams, and decompose jitter. Deliver IBIS-AMI models for Tx, Rx, Redriver, or Retimer by exporting to Simulink and compiling .ami/.ibs/.dll/.so files. Covers the full arc from initial design exploration and parameter optimization to compliance testing and compiled model validation, including custom datapath blocks for nonstandard equalization.
— the description by MathWorks

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

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/matlab/matlab-model-serdes-systems/download
  2. Unzip 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/.so

  • Scripting 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/RxModel are Transmitter/Receiver objects — not cell arrays. Construct with Transmitter('Blocks', {block1, block2}). Transmitter requires single-quoted property names — Transmitter("Blocks", ...) throws an ismember error. Receiver and all other classes accept double quotes

  • Signal conversion functions require column vectors — impulse2pulse, pulse2stateye, etc. error on row vectors

  • Include AnalogModel and JitterAndNoise for realistic results — bare Transmitter/Receiver without analog models produce optimistic COM (1-2 dB higher). See reference/equalization-tuning.md for parameter guidance (rise time, parasitic C, termination R)

Equalization
  • Set WaveType explicitly 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. After analysis(), sys.RxModel.Blocks{k}.TapWeights still 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 outparams with Mode=1 for instant convergence, or use Mode=2 with 10x EqualizationGain (9.6e-04) for self-converging chains

  • Set Modulation on 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.EW is in picoseconds (already scaled) — do NOT multiply by 1e12. EH is 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 using filter() for time-domain convolution, multiply by dt: filter(impulse * dt, 1, wave). Without scaling, amplitudes blow up by ~10^11

  • pulse2wave operates on the stimulus provided — the output modulation depends on the input pattern (NRZ or PAM-N)

  • 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.AMI runner and the AMI Simulink block need both SerDes Toolbox and Signal Integrity Toolbox

  • AMI GetWave: call in a chunked loop — serdes.AMI passes BlockSize (default 1024) to AMI_GetWave, so only BlockSize samples are processed per call. You must call the object in a for loop with BlockSize-length chunks. State is preserved between calls via the DLL memory handle

  • AMI GetWave: set SkipFirstBlock = false when calling from MATLAB — the default (true) is for Simulink's internal signal buffering and causes the first block to pass through unprocessed

  • AMI Init: RowSize must match impulse length — serdes.AMI crashes MATLAB (process termination, no error) if RowSize doesn't match numel(impulse)

  • AMI generation requires Simulink model — use IbisAmiManager GUI or serdes.AMIExport with export() 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.

  1. Design — Create a SerdesSystem with Tx/Rx blocks and channel (loss model or S-parameters)

  2. Analyze — Run analysis for statistical results, plotStatEye for eye diagrams, analysisReport for metrics

  3. Sweep — Vary channel loss, FFE taps, CTLE gain, DFE taps, or jitter to map the design space

  4. Compare — Evaluate architectures (FFE-only vs FFE+CTLE vs FFE+CTLE+DFE) using COM, eye height, eye width

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

  1. Load — Import the waveform and define timing (SampleInterval, SymbolTime)

  2. Equalize — Stream through datapath blocks (FFE, CTLE, DFECDR) with WaveType = "Sample"

  3. Analyze — Build an eye diagram with eyeDiagramSI, extract metrics (eye height, COM, VEC)

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

  1. Export — Call exportToSimulink(sys) to generate a Simulink model from the frozen design

  2. Configure — Set AMI parameters, IBIS component/pin data, and model type via IbisAmiManager or serdes.AMIExport

  3. Generate — Build .ami/.ibs and compile .dll/.so via serdes.AMIExport with export()

  4. Validate — Load compiled DLL/SO with serdes.AMI, compare against behavioral reference (Init for impulse, GetWave for waveform)

  5. Cross-check — The Simulink path (sim with Rx WaveOut) is the preferred time-domain reference. Compare against: statistical analysis(), system objects direct chain, and compiled AMI DLLs. See reference/simulink-serdes-simulation.md

  6. Iterate — 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:

TypeInit_Returns_ImpulseGetWave_ExistsUse For
Init-OnlytruefalseLTI equalization (fixed FFE, CTLE). Supports statistical analysis
GetWave-OnlyfalsetrueTime-domain only. No statistical analysis
DualtruetrueAdaptive 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

ClassPurpose
SerdesSystemTop-level system. Methods: analysis, plotStatEye, plotImpulse, plotPulse, plotAlignedPulse, plotWavePattern, analysisReport, exportToSimulink
TransmitterTx container. Construct: Transmitter('Blocks', {serdes.FFE(...)})
ReceiverRx container. Construct: Receiver('Blocks', {serdes.CTLE(...), serdes.DFECDR(...)})
ChannelDataChannel spec. Props: ChannelLossdB, ChannelLossFreq (default 5 GHz — must override to Nyquist), ChannelDifferentialImpedance, or Impulse/dt
JitterAndNoiseIBIS 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.AMIRun compiled AMI DLLs/SOs. Call: [waveOut, impulseOut] = ami(waveIn, impulseIn, clockIn)
serdes.AMIExportProgrammatic AMI export (R2026a+). Methods: export, getExportSettings. Props: ModelTypeTx, DLLFiles, LinuxCrossCompile
SParameterChannelS-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
eyeDiagramSIWaveform eye diagram (R2024a+). Step: eyeObj(wave) — no output. Metrics: eyeHeight, eyeWidth, com, vec, margin
ctlefitCTLE pole/zero fitter. Import: ctlefit.readcsv. Output: GPZ matrix for serdes.CTLE("Specification", "GPZ Matrix")
Datapath Blocks
BlockRoleMode ValuesKey Properties
serdes.FFEFeed-forward equalizer0, 1TapWeights, TapSpacing, Normalize
serdes.CTLEContinuous-time linear EQ0, 1, 2Specification, DCGain, ACGain, PeakingGain, GPZ
serdes.DFECDRDFE + clock recovery0, 1, 2TapWeights, CDRMode, PhaseDetector, Count
serdes.DFEStandalone DFE0, 1, 2TapWeights, EqualizationGain, EqualizationStep
serdes.CDRStandalone CDR0, 1CDRMode, Count, Step, Sensitivity. Mode is deprecated
serdes.AGCAuto gain control0, 1TargetRMSVoltage, MaxGain, AveragingLength
serdes.VGAVariable gain amplifier0, 1Gain
serdes.SaturatingAmplifierLimiting amplifier0, 1Limit, LinearGain, Specification
serdes.PassThroughNo-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 SerdesSystem for programmatic design; serdesDesigner for interactive exploration. Always run analysis/plotStatEye before exporting

  • CRITICAL: ChannelLossFreq defaults 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. Use SParameterChannel for real channels

  • analysis() does not auto-optimize FFE taps — use canonical de-emphasis with sum(abs(taps)) ≈ 1.0

  • DFE taps initialized to zero are optimized by the statistical solver automatically

  • Industry reference designs: serdesDesigner or openExample('serdes/PCIe5TransmitterReceiverIBISAMIModelExample'). See reference/equalization-tuning.md for starting-point configurations

Visualization and Metrics
  • All SerdesSystem plot methods (plotStatEye, plotImpulse, plotPulse, plotAlignedPulse, plotWavePattern) render into the current axes — use tiledlayout/nexttile or subplot for multi-panel layouts

  • eyeDiagramSI (R2024a+) for waveform eye diagrams; jitter (R2024b+) for jitter decomposition

  • DFECDR/DFE in "Sample" WaveType require scalar (sample-by-sample) input; FFE/CTLE accept full vectors

  • When generating PRBS waveforms via pulse2wave, ask the user for PRBS order and symbol count — default PRBS-10 (1023 symbols) if unspecified

  • Use serdes.utilities.SignalIntegrityColorMap (not hot/parula) for pulse2stateye plots. For compliance, use margin(eyeObj, eyeMask)

  • See reference/visualization-and-metrics.md for all plot methods, metrics fields/units, eyeDiagramSI, and jitter

AMI Export and Validation
  • Use serdes.AMIExport with export() for programmatic AMI generation — not slbuild (legacy, R2025b and earlier only)

  • Validate compiled DLLs/SOs with serdes.AMI before 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 paths

  • AMI export parameters on Simulink blocks use *AMI suffix ('ModeAMI', 'TapWeightsAMI'); model-level settings go through IbisAmiManager or serdes.AMIExport

  • No compiled DLLs/SOs ship with the toolbox. Cross-compile for Linux .so via serdes.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.

  1. Create a .m file (e.g., serdes_pam4_design.m), run via run_matlab_file, iterate by editing and re-running

  2. Deliver a polished script — %% Parameters block at top, %% Section headers, summary fprintf at end

References
Load when...Reference
Building or modifying a SerdesSystemreference/serdes-api-reference.md
Debugging wrong API names or silent failuresreference/common-mistakes.md
Working with S-parameter files or crosstalkreference/channel-modeling.md
Tuning CTLE, FFE, DFE, or fitting transfer functionsreference/equalization-tuning.md
Sweeping parameters or running GA optimizationreference/optimization.md
Plotting eyes, reading metrics, or decomposing jitterreference/visualization-and-metrics.md
Equalizing captured or imported waveforms directlyreference/waveform-processing.md
Exporting to Simulink, compiling AMI DLLs, or validating AMI modelsreference/programmatic-ami-generation.md
Scripting Simulink simulations or parsim sweepsreference/simulink-serdes-simulation.md
Building custom datapath blocksreference/custom-datapath-blocks.md
Looking up utility functions (SNR, ICN, resample)reference/serdes-utilities.md

Files

reference/serdes-api-reference.md

SerDes Toolbox Class and Function Reference

SerdesSystem

Top-level design and analysis object.

Construction
sys = SerdesSystem(...
    'TxModel', Transmitter('Blocks', {block1, block2}), ...
    'RxModel', Receiver('Blocks', {block3, block4}), ...
    'SymbolTime', 100e-12, ...
    'SamplesPerSymbol', 16, ...
    'Modulation', 2, ...
    'Signaling', "Differential", ...
    'BERtarget', 1e-6);
Properties
PropertyTypeDescription
TxModelTransmitterTx container with Blocks, RiseTime, VoltageSwingIdeal, AnalogModel
RxModelReceiverRx container with Blocks, AnalogModel
NamestringSystem name
SymbolTimedoubleDuration of one symbol (s)
SamplesPerSymbolintegerSamples per symbol (default 16; valid: 8, 16, 32, 64, 128). dt = SymbolTime / SamplesPerSymbol
ModulationintegerModulation levels: 2 (NRZ), 3 (PAM3), 4 (PAM4), up to 16
Signalingstring"Differential" or "Single Ended"
BERtargetdoubleTarget BER for statistical analysis (default 1e-6)
ChannelDataChannelDataChannel specification (see below)
JitterAndNoiseJitterAndNoiseJitter/noise parameters (see below)
dtdoubleRead-only. Computed sample interval
ImpulseResponsedoubleRead-only. Channel impulse response after analysis
EyestructRead-only. Statistical eye results
WavestructRead-only. Equalized/unequalized waveforms
MetricsstructRead-only. BER eye contours and bathtub data
Choosing BERtarget

BERtarget sets the BER contour at which eye height and eye width are measured. It does not affect COM (which uses its own internal BER assumption). Common values:

StandardBERtargetNotes
IEEE 802.3 (Ethernet)1e-6Default; used for 100G/200G/400G/800G specs
OIF CEI1e-15More conservative; tighter eye opening
PCIe Gen5/61e-6Post-FEC target
USB41e-4Relaxed pre-FEC target

Lower BERtarget → smaller reported EH/EW (the eye is measured further into the tails of the distribution). When comparing results across designs, keep BERtarget consistent.

Metrics.summary Fields

After analysis(sys), sys.Metrics.summary contains:

FieldTypeUnitsDescription
COMestimatescalardBChannel Operating Margin
EHvectorVoltsEye height at BERtarget. PAM-N returns N-1 values (e.g., PAM4: 3, PAM8: 7)
bestEHvectorVoltsBest-case eye height (optimistic sampling)
EWvectorPicoseconds (already scaled — do NOT multiply by 1e12)Eye width at BERtarget
VECscalarPercentVertical eye closure
eyeAreasvector—Normalized eye area per eye opening
eyeLinearityscalarRatioPAM-N level linearity (1.0 = perfectly symmetric)

Units warning: EH is in volts (multiply by 1e3 for mV), but EW is already in picoseconds. This is inconsistent with every other timing value in the toolbox (which use seconds).

analysis() outparams — Adapted Block Parameters

results.outparams is a cell array with one entry per datapath block (Tx blocks first, then Rx blocks in order). Each cell is either a double (e.g., FFE output) or a struct keyed by block class name.

Adapted DFE/CTLE parameters live here, NOT on the block object. After analysis(), sys.RxModel.Blocks{k}.TapWeights still holds the initial values. The solver's adapted values are only in outparams.

% With Tx FFE + Rx CTLE + Rx DFECDR:
% results.outparams{1} — FFE (double)
% results.outparams{2} — CTLE (struct with field 'CTLE')
% results.outparams{3} — DFECDR (struct with field 'DFECDR')

% Extract adapted DFE taps
for p = 1:numel(results.outparams)
    if isstruct(results.outparams{p}) && isfield(results.outparams{p}, 'DFECDR')
        adaptedTaps = results.outparams{p}.DFECDR.TapWeights;
        adaptedPhase = results.outparams{p}.DFECDR.Phase;
    end
end
Methods
MethodReturnsDescription
analysis(sys)struct with t1, impulse, pulse, t2, wave, outparamsRun statistical analysis
plotStatEye(sys)—Plot statistical eye diagram
plotImpulse(sys)—Plot equalized/unequalized impulse
plotPulse(sys)—Plot equalized/unequalized pulse
plotAlignedPulse(sys)—Plot aligned pulse response
plotWavePattern(sys)—Plot PRBS waveform
analysisReport(sys)—Print analysis summary to command window
exportToSimulink(sys)—Export to Simulink model
validateSerdesSystem(sys)—Validate system configuration

ChannelData

Three channel definition modes (mutually exclusive):

  1. Lossy model (default): ChannelLossdB + ChannelLossFreq + ChannelDifferentialImpedance

  2. S-parameter model: via serdesDesigner export

  3. Direct impulse: Impulse + dt

IMPORTANT: To select impulse mode, pass "Impulse" and "dt" as constructor name-value pairs. Assigning sys.ChannelData.Impulse = ... after construction does NOT switch the mode — the loss model silently takes priority.

% CORRECT -- impulse mode via constructor
channel = ChannelData("Impulse", impulseVector, "dt", sampleInterval);
sys = SerdesSystem("ChannelData", channel, ...);

% WRONG -- loss model runs, impulse is ignored
sys.ChannelData.Impulse = impulseVector;
sys.ChannelData.dt = sampleInterval;
PropertyDescription
ChannelLossdBChannel loss in dB at ChannelLossFreq
ChannelLossFreqFrequency for loss specification (Hz). Default: 5 GHz — almost always wrong. Set to Nyquist: 1/(2*SymbolTime)
ChannelDifferentialImpedanceDifferential impedance (ohms)
ImpulseDirect impulse response (column vector)
dtSample interval for direct impulse (s)
EnableCrosstalkEnable crosstalk modeling (ICN mode only — multi-column impulse auto-enables)
CrosstalkSpecification"CEI-28G-SR" (default), "CEI-25G-LR", "CEI-28G-VSR", "100GBASE-CR4", or "Custom"
FEXTICNFEXT integrated crosstalk noise (V RMS, default 0.015). Only with "Custom" spec
NEXTICNNEXT integrated crosstalk noise (V RMS, default 0.010). Only with "Custom" spec
fbBaud rate for ICN noise shaping (Hz, auto-derived from SymbolTime)
Aft / AntAggressor amplitude for FEXT/NEXT (Vpp, default 1.2)
Tft / TntAggressor rise time for FEXT/NEXT (s, default 9.6e-12)
OptionSelRead-only. Internal mode selector (1=impulse, 3=loss model)

JitterAndNoise

IBIS 7.0 compliant jitter and noise parameters. Each jitter property is a SimpleJitter object with Value, Type, and Include fields. Assign a scalar to set the value directly; access the sub-fields for unit control.

RxClockMode

Controls how the Rx sampling clock is modeled:

ModeDescription
"ideal"Perfect clock — no Rx clock jitter. Rx_Clock_Recovery_* parameters ignored
"clocked"Clock with jitter — Rx_Clock_Recovery_* parameters affect the sampling eye
"convolved"Convolves clock jitter with data jitter (statistical combination)
"normal"Normal clock recovery model

Key rule: Set RxClockMode to "clocked" for Rx clock recovery jitter to affect analysis. With "ideal", all Rx_Clock_Recovery_* parameters are ignored.

Tx Jitter
PropertyDefaultConvention
Tx_Rj0Random jitter — standard deviation (not peak-to-peak)
Tx_Dj0Deterministic jitter — peak-to-peak
Tx_DCD0Duty cycle distortion — peak-to-peak
Tx_Sj0Sinusoidal jitter — peak-to-peak amplitude
Tx_Sj_Frequency0Sinusoidal jitter frequency (Hz, not UI)
Rx Jitter

Requires RxClockMode = "clocked" — Rx jitter is modeled as clock jitter and has NO effect in "ideal" mode. Rx jitter and Rx Clock Recovery jitter of the same type produce identical degradation.

PropertyDefaultConvention
Rx_Rj0Random jitter — standard deviation
Rx_Dj0Deterministic jitter — peak-to-peak
Rx_DCD0Duty cycle distortion — peak-to-peak
Rx_Sj0Sinusoidal jitter — peak-to-peak amplitude
Rx Clock Recovery Jitter

Only active when RxClockMode is "clocked", "convolved", or "normal". Ignored when RxClockMode = "ideal".

PropertyDefaultConvention
Rx_Clock_Recovery_Mean0CDR mean phase offset. No measurable effect on COM in statistical analysis
Rx_Clock_Recovery_Rj0CDR random jitter — standard deviation
Rx_Clock_Recovery_Dj0CDR deterministic jitter — peak-to-peak
Rx_Clock_Recovery_Sj0CDR sinusoidal jitter — peak-to-peak
Rx_Clock_Recovery_DCD0CDR duty cycle distortion — peak-to-peak
Rx Noise
PropertyDefaultConvention
Rx_Receiver_Sensitivity0Minimum detectable voltage (V). No measurable effect on COM in statistical analysis
Rx_GaussianNoise0Additive Gaussian noise — RMS (V)
Rx_UniformNoise0Additive uniform noise — peak (V)
Units: Seconds or UI

Each jitter property wraps a SimpleJitter object with Value, Type, and Include fields. The Type field accepts "Float" (seconds, default) or "UI" (unit intervals). Both work correctly — analysis() converts UI values to seconds using the system's SymbolTime.

Critical: Include defaults to false. Direct scalar assignment (jn.Tx_Rj = 1e-12) auto-sets Include = true and Type = "Float". When constructing SimpleJitter manually, always set Include = true explicitly.

% Direct assignment in seconds (simplest — auto-sets Include=true)
jn = JitterAndNoise('RxClockMode', 'clocked');
jn.Tx_Rj = 1e-12;     % 1 ps RMS (Type="Float", Include=true automatic)
jn.Tx_Dj = 5e-12;     % 5 ps peak-to-peak

% Using UI type via SimpleJitter constructor (Include=true required)
sj = SimpleJitter('Value', 0.05, 'Include', true, 'Type', 'UI');
jn.Tx_DCD = sj;       % 0.05 UI → analysis converts via SymbolTime

% Or convert from UI spec to seconds manually
uiSpec = 0.05;  % 5% UI from a datasheet
jn.Tx_DCD = uiSpec * symbolTime;  % explicit conversion

% Disable a specific jitter component
sj = jn.Rx_Sj;
sj.Include = false;
jn.Rx_Sj = sj;
Construction Example
% Typical jitter budget for a 56 Gbps PAM4 link
jn = JitterAndNoise('RxClockMode', 'clocked');
jn.Tx_Rj = 0.5e-12;                  % 0.5 ps RMS
jn.Tx_Dj = 2e-12;                    % 2 ps p-p
jn.Tx_DCD = 1e-12;                   % 1 ps DCD
jn.Rx_Rj = 0.3e-12;                  % 0.3 ps RMS
jn.Rx_Clock_Recovery_Rj = 0.2e-12;   % 0.2 ps CDR RJ
jn.Rx_Clock_Recovery_Dj = 1e-12;     % 1 ps CDR DJ
jn.Rx_GaussianNoise = 0.5e-3;        % 0.5 mV RMS

sys = SerdesSystem('JitterAndNoise', jn, ...);

serdes.AMI

Run and test compiled IBIS-AMI DLLs/SOs. Requires SerDes Toolbox + Signal Integrity Toolbox.

Calling Convention
[waveOut, impulseOut] = ami(waveIn, impulseIn, clockIn)
  • waveIn — Input waveform (column vector of BlockSize length for GetWave). For Tx: stimulus. For Rx: channel output.

  • impulseIn — Channel impulse response (column vector of RowSize length, optionally with aggressors).

  • clockIn — Clock times vector of BlockSize length ending with -1, or just -1 (scalar) for Init-only mode.

  • waveOut — Output waveform.

  • impulseOut — Output impulse response (modified by Init on first call, zeros on subsequent GetWave calls).

GetWave chunked loop: AMI_GetWave processes exactly BlockSize samples per call. When calling from MATLAB with a waveform longer than BlockSize, you must call the object in a for loop with BlockSize-length chunks. The DLL state is preserved between calls via the memory handle — Init fires only on the first call:

nPad = ceil(N / blockSize) * blockSize;
wavePad = [wave; zeros(nPad - N, 1)];
waveOut = zeros(nPad, 1);
clockIn = -ones(blockSize, 1);
for k = 1:nPad/blockSize
    idx = (k-1)*blockSize + (1:blockSize);
    [waveOut(idx), ~] = ami(wavePad(idx), impulse, clockIn);
end
waveOut = waveOut(1:N);
Properties
PropertyDefaultDescription
LibraryName''Name of the AMI DLL/SO (without extension)
LibraryPath''Path to the DLL/SO directory
InputString''AMI parameter input string
SymbolTime1e-10Symbol time (s)
SampleInterval6.25e-12Sample interval (s)
BlockSize1024Number of samples passed to each AMI_GetWave call
RowSize7065Impulse response length — must match numel(impulseIn) or MATLAB crashes
Aggressors0Number of aggressor channels
PassThroughfalsePass-through mode (bypass DLL)
InitOnlytruetrue = Init flow only, false = Init + GetWave
SkipFirstBlocktrueSkip first GetWave block. Set false when calling from MATLAB — the default true is for Simulink's internal signal buffering and causes the first block to pass through unprocessed
OutputName'AMIOut'Workspace variable name (Simulink only, ignored in MATLAB)
AMIDatastructOutput data structure from DLL

Static method: serdes.AMI.generateDefaultInputString(amiFilePath) — parse .ami file and return default input string.

serdes.AMIExport (R2026a+)

Programmatic AMI export object. Mirrors the IbisAmiManager GUI.

AMIExport = serdes.AMIExport("modelName")
AMIExport.ModelsToExport = "Both Tx and Rx";
AMIExport.DLLFiles = true;
AMIExport.LinuxCrossCompile = true;
export(AMIExport);
PropertyDefaultDescription
ModelName(read-only)Simulink model name
ModelConfiguration"TxandRx"System model type
ModelTypeTx"Dual model"Tx export type: "Dual model", "GetWave only", "Init only"
ModelTypeRx"Dual model"Rx export type
ModelsToExport"Both Tx and Rx"Which models to export
DLLFilestrueExport compiled DLL/SO
AMIFilestrueExport .ami files
IBISFiletrueExport .ibs file
LinuxCrossCompilefalseBuild Linux .so from Windows
ObfuscatefalseObfuscate executables
TargetDirstringOutput directory

Methods: export(AMIExport), getExportSettings(AMIExport).

SParameterChannel

Convert S-parameter Touchstone files to time-domain impulse responses with analog Tx/Rx termination modeling. Uses rational fitting internally to produce a causal impulse response from frequency-domain S-parameter data.

Construction
spCh = SParameterChannel("FileName", "channel.s4p");

IMPORTANT: The constructor requires "FileName" as a name-value argument. Positional syntax (SParameterChannel("channel.s4p")) does not work.

Properties — Input
PropertyDefaultDescription
FileName"default.s4p"Touchstone file path (.s2p, .s4p, .s8p, etc.)
PortOrder[]Port ordering [in+ out+ in- out-]. Empty = auto-detect. For files with convention 1=in+, 2=in-, 3=out+, 4=out-, use [1 3 2 4]
MaxNumberOfPoles1000Maximum poles for rational model fit
ErrorTolerance-40Desired error tolerance (dB) for rational model fit
Properties — Timing
PropertyDefaultDescription
SampleInterval6.25e-12Output sample interval (s). Must match SerdesSystem dt
StopTime1e-7Impulse response duration (s). Use >= 60 ns for SerdesSystem integration
Properties — Analog Model
PropertyDefaultDescription
TxAmplitude1Stimulus input amplitude (V, single-ended)
TxRiseTime1e-1120%-80% rise time of stimulus (s)
TxR50Tx termination resistance (ohms, single-ended)
TxC1e-13Tx termination capacitance (F)
RxR50Rx termination resistance (ohms, single-ended)
RxC2e-13Rx termination capacitance (F)
Properties — Read-Only Outputs
PropertyDescription
ImpulseResponseChannel impulse response (column vector). Continuous-time scaling: sum(ImpulseResponse) * SampleInterval gives DC gain
tTime vector (column, s)
TransferFunctionSystem transfer function (column vector, complex)
ChannelTransferFunctionChannel-only transfer function (excludes Tx/Rx analog model)
fS-parameter frequency vector (column, Hz)
RationalResultsrational object with fitting statistics
PortOrderUsedActual port order used after auto-detection
RiseTimeUncertaintyUncertainty due to rise time discretization (s, negative)
Integration with SerdesSystem

To feed an S-parameter impulse into SerdesSystem, construct ChannelData with "Impulse" and "dt" name-value pairs in the constructor. Do NOT assign sys.ChannelData.Impulse after construction — the internal mode selector stays on loss-model and ignores the impulse.

% CORRECT -- use ChannelData constructor
spCh = SParameterChannel("FileName", "channel.s4p");
spCh.SampleInterval = symbolTime / samplesPerSymbol;
spCh.StopTime = 60e-9;
spCh.PortOrder = [1 3 2 4];

channel = ChannelData( ...
    "Impulse", spCh.ImpulseResponse, ...
    "dt", spCh.SampleInterval);

sys = SerdesSystem( ...
    "ChannelData", channel, ...
    "SymbolTime", symbolTime, ...
    "SamplesPerSymbol", samplesPerSymbol, ...
    ... );
% WRONG -- impulse is silently ignored, loss model runs instead
sys.ChannelData.Impulse = spCh.ImpulseResponse;
sys.ChannelData.dt = spCh.SampleInterval;
Key Gotchas
  • StopTime: Use >= 60 ns for SerdesSystem integration. Short durations (e.g., 20 ns) produce too few samples and analysis may give incorrect metrics.

  • SampleInterval: Must match SerdesSystem.dt (SymbolTime / SamplesPerSymbol).

  • PortOrder: For 4-port files with convention 1=in+, 2=in-, 3=out+, 4=out-, set [1 3 2 4]. Check PortOrderUsed after construction to verify.

  • Multi-port files: SParameterChannel handles .s8p/.s12p/.s16p directly. ImpulseResponse returns an Nx(K) matrix: column 1 = victim thru, columns 2+ = aggressor coupling. Pass the full matrix to ChannelData("Impulse", ir, "dt", dt) to include crosstalk.

See reference/channel-modeling.md for a complete S-parameter workflow.

Signal Conversion Functions

All functions require column vector inputs.

FunctionSignatureDescription
impulse2pulseP = impulse2pulse(I, N, dt)Impulse to pulse response
impulse2stepS = impulse2step(I, dt)Impulse to step response
pulse2impulseI = pulse2impulse(P, N, dt)Pulse to impulse
step2impulseI = step2impulse(S, dt)Step to impulse
pulse2waveW = pulse2wave(P, D, N)Pulse + data to waveform
wave2pulseP = wave2pulse(W, D, N)Waveform to pulse
prbs[P, seed] = prbs(O, N, seed, reverse)PRBS generator. O = order (5-40), N = length. Returns column vector of 0/1. Optional seed for reproducibility, reverse for time-reversed LFSR
pulse2stateye[S, V, T] = pulse2stateye(P, N, M)Statistical eye. M = modulation levels
pulse2pda[E, T, D] = pulse2pda(P, N, M)Peak distortion analysis eye
optPulseMetricM = optPulseMetric(P, N, dt, BER)Returns struct with fields: maxEyeHeight, maxMeanEyeHeight, maxCOM, eyeArea, eyeWidth, centerEyeHeight, centerMeanEyeHeight, centerCOM, SNR, usedBER. LTI-only — does not account for jitter
pulseRecoverClockC = pulseRecoverClock(P, N)Clock recovery (hula-hoop algorithm)
applyLinearFilter[Y, Xh, Yh] = applyLinearFilter(X, Xh, Yh, B, A)Recursive filter (Direct Form I)

Waveform Analysis (R2024a+)

Class/FunctionSignatureDescription
eyeDiagramSIeyeObj = eyeDiagramSI; eyeObj(wave)System object — builds 2-D eye histogram from waveform. No output from step. Do NOT name the variable eye — it shadows MATLAB's built-in eye(). Metrics via eyeHeight, eyeWidth, com, vec, eyeArea, eyeLinearity, bathtub, margin
jitterJ = jitter(y, SampleInterval=s, SymbolTime=t, Plot=false)Jitter decomposition. Returns struct: TJrms, TJpkpk, RJrms, DJpkpk, DDJpkpk, DCDrms, ISIpkpk, SJa/SJf/SJp

See reference/visualization-and-metrics.md for eyeDiagramSI/jitter property tables and reference/waveform-processing.md for direct equalization patterns.

Fitting Tools

ctlefit

Programmatic interface to the CTLE Fitter. Fits rational pole/zero models to CTLE frequency response data and produces a GPZ matrix for serdes.CTLE.

Construction
[f, H] = ctlefit.readcsv(csvFile);   % Import from CSV
obj = ctlefit('f', f, 'H', H, 'SampleInterval', dt, ...
    'MaxNumberOfPoles', 2, 'ErrorTolerance', -40, ...
    'TendsToZero', 1, 'UseCommonPoles', 0, 'PaddedPole', 1e11);
Import
Static MethodDescription
ctlefit.readcsv(filename)Read CTLE frequency response from CSV. Returns [f, H]. Header format: freq,real,imag,real,imag,... (also accepts db,phaseDeg, db,phaseRad, mag,phaseDeg, mag,phaseRad)
Constructor Properties
PropertyTypeDescription
fdouble vectorFrequency vector (Hz)
Hcomplex matrixComplex transfer functions (nFreq x nSettings)
SampleIntervaldoubleSample interval (s). Typically SymbolTime / SamplesPerSymbol
MaxNumberOfPolesintegerMaximum number of poles per setting (1, 2, or 3). Default: 2
ErrorTolerancedoubleMaximum acceptable fit error (dB). Default: -40
TendsToZerological1 = response rolls off at high frequency (typical for CTLE). 0 = flat
UseCommonPoleslogical1 = force all settings to share pole locations. 0 = independent poles
PaddedPoledoubleExtra high-frequency pole (Hz) for rolloff. Example: 1e11
Output
PropertyFormatDescription
GPZmatrixFitted poles/zeros/gains. Format: [Gain(dB) Pole1(Hz) Zero1(Hz) Pole2(Hz); ...]. One row per CTLE gain setting. Poles/zeros are negative (left half-plane). Feeds directly into serdes.CTLE('Specification', "GPZ Matrix", 'GPZ', gpz)
Preprocessing Methods
MethodDescription
truncateAbove(obj, fMax)Remove frequency data above fMax (Hz). Use 2 * fNyquist to cut fitting noise
truncateBelow(obj, fMin)Remove frequency data below fMin (Hz)
resample(obj, fNew)Resample transfer functions onto new frequency vector
removeDelay(obj)Remove group delay from transfer functions
Visualization Methods
MethodDescription
plot(obj, format, which, plotType)Magnitude response. format: "dB", "mag". which: "All" or index. plotType: "semilogx", "plot"
plotPulse(obj, which)Pulse response of fitted model
plotError(obj, which)Fit error (deviation between fitted and original)
plotFitMetric(obj, which)Fit quality metric plot
plotPoleZero(obj, which)Pole-zero map for each gain setting
Typical Workflow
[f, H] = ctlefit.readcsv("ctle_data.csv");
obj = ctlefit("f", f, "H", H, "SampleInterval", dt, "MaxNumberOfPoles", 2);
truncateAbove(obj, 2 * fNyquist);
gpz = obj.GPZ;
ctle = serdes.CTLE("Specification", "GPZ Matrix", "GPZ", gpz);
Other Fitting Tools
ToolDescription
ctlefitterCTLE Fitter GUI app (interactive version of ctlefit)
SParameterChannelS-parameter fitting (also listed above)
sParameterFitterS-parameter Fitter GUI app

GUI Apps

AppLaunchPurpose
serdesDesignerserdesDesignerMain design app — design, analyze, export
IbisAmiManagerFrom Configuration blockAMI parameter tree, IBIS files, DLL generation
ctlefitterctlefitterCTLE pole/zero fitting
sParameterFittersParameterFitterS-parameter to impulse fitting

serdes.utilities Namespace

Signal quality metrics, signal manipulation, and formatting functions. All called as serdes.utilities.<FunctionName>(...). See reference/serdes-utilities.md for full signatures, gotchas, and usage patterns.

FunctionPurposeKey Output
SERSymbol error rate class.SymbolErrorRate after calculateSER()
SNR(P, N)Signal-to-noise ratio from pulseLinear ratio (not dB)
WaveEyeHeight(wave, N)Max eye height by waveform folding[maxEH, upper, lower] in volts
icn(f, Sxt, fb)Integrated crosstalk noise (OIF-CEI)V RMS
poleZeroDefine(NV)CTLE poles/zeros from peaking specs[G, P, Z] or GPZ matrix
SoftClipper(gain, limit)Cubic soft-clipper curve[Nx2] Vin/Vout
resampleImpulse(X, dtIn, dtOut, normalize)Resample impulse responseColumn matrix
shiftPulse(pulse, N)Center pulse for eye diagramsShifted pulse + cursor index
floatingTaps(taps, fixed, groups, size)DFE floating tap placementConstrained tap vector
dt2Trf / trf2dtIBIS ↔ LTI rise time conversionRise time (s)
db(x)20*log10(abs(x))dB value
num2prefix(X, unit)SI prefix formatting"100 ps", "14.1 GHz"
SignalIntegrityColorMapStandard eye diagram colormapColormap matrix
pulseRecoverClock(P, N)Clock recovery (hula-hoop)Clock index

System objects used as Simulink blocks in exported SerDes models. See reference/simulink-serdes-simulation.md for scripted simulation workflows.

BlockPurposeKey Properties
serdes.StimulusPRBS pattern + jitterSpecification (10 options), Modulation (2-32), Dj/Rj/DCD/Sj, BinaryToPAMnMapping
serdes.ChannelLossLossy transmission line (IEEE 802.3bj)Loss, TargetFrequency, Zc, TxR/RxR/TxC/RxC, EnableCrosstalk, FEXTICN/NEXTICN
serdes.ChannelImpulseChannel from impulse matrixImpulseMatrix (Nx1 or Nx2xM), SampleInterval
serdes.EyeAnalyzerWaveform eye analysis (MATLAB-only)ClockMode, IgnoreSymbols, jitter/noise impairments, EyeHistogram (read-only)

Pattern: Programmatic System Design and Analysis

% Create a 56 Gbps PAM4 SerDes system with full analog models
sys = SerdesSystem(...
    'TxModel', Transmitter('Blocks', ...
        {serdes.FFE('TapWeights', [-0.1 0.7 -0.2])}, ...
        'AnalogModel', AnalogModel('R', 50, 'C', 1e-13), ...
        'RiseTime', 1e-11, 'VoltageSwingIdeal', 1), ...
    'RxModel', Receiver('Blocks', ...
        {serdes.CTLE('Specification', "DC Gain and AC Gain", ...
                      'DCGain', 0, 'ACGain', 12, ...
                      'PeakingFrequency', 14e9), ...
         serdes.DFECDR('TapWeights', zeros(1, 5), 'Mode', 2)}, ...
        'AnalogModel', AnalogModel('R', 50, 'C', 2e-13)), ...
    'ChannelData', ChannelData('ChannelLossdB', 15, ...
        'ChannelLossFreq', 14e9, 'ChannelDifferentialImpedance', 100), ...
    'JitterAndNoise', JitterAndNoise('RxClockMode', 'clocked'), ...
    'SymbolTime', 35.71e-12, ...
    'SamplesPerSymbol', 16, ...
    'Modulation', 4, ...
    'Signaling', 'Differential', ...
    'BERtarget', 1e-6);

% Run analysis — returns struct with t1, impulse, pulse, t2, wave, outparams
results = analysis(sys);
plotStatEye(sys);
analysisReport(sys);

% Read metrics — EH is in volts, EW is in picoseconds (already scaled)
m = sys.Metrics.summary;
fprintf("COM: %.2f dB, EH: %.1f mV, EW: %.1f ps\n", m.COMestimate, m.EH(2)*1e3, m.EW(2));

% Read adapted DFE taps from outparams (NOT from the block object)
% outparams is a cell array — one entry per datapath block in Tx/Rx order
for p = 1:numel(results.outparams)
    if isstruct(results.outparams{p}) && isfield(results.outparams{p}, 'DFECDR')
        adaptedTaps = results.outparams{p}.DFECDR.TapWeights;
        fprintf("Adapted DFE taps: %s\n", mat2str(adaptedTaps, 4));
    end
end

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