Matlab Analyze Pcb Pdn
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- Software development
- BSD-2-Clause
- No issues found
From the skill’s files
Taken from the skill’s own files (its description, section headings and stated usage). Not an AutoGineer summary, and not written by the author as one.
PDN DC voltage/current analysis, IR drop, design rule checking, and multi-net batch analysis on imported PCB layouts. TRIGGER: user asks about power integrity, PDN analysis, IR drop, voltage distribution, current density, power nets, or design rule checking on a PCB. Invoke BEFORE writing code — the PDN API chain is specialized and non-obvious. SKIP: importing a PCB file (use matlab-read-pcb-layout), EM field/S-parameter extraction (use matlab-analyze-em), material/stackup setup only (use matlab-manage-pcb-material), transmission line design (use matlab-design-pcb-transmission-line). pcbFileRead imports a PCB file and returns an object for hierarchical inspection. Supported formats: native directory (CSV files), ODB++ (zipped or unzipped), and Cadence Allegro .brd (requires one-time extractaSetup()).
What it does
- When to Use
- When NOT to Use
- Typical Workflow
- Quick Reference
- PCB Import and Net Discovery
- cadnet Object
When to use it
- TRIGGER: user asks about power integrity, PDN analysis, IR drop, voltage distribution, current density, power nets, or design rule checking on a PCB.
- Analyzing DC voltage and current distribution on PCB power rails
- Checking design rules (max current density, voltage margins, via current limits)
- Discovering and listing power nets on an imported PCB layout
- Assigning source/load/sense topology for PDN analysis
- Running batch analysis across multiple power rails on a board
Advantages
The skill’s files do not state this.
Usage examples
The skill’s files do not state this.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/matlab/matlab-analyze-pcb-pdn/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-analyze-pcb-pdn.zip -d .agents/skills
Documentation by MathWorks
Analyzing Power Distribution Networks (PDN)
When to Use
Analyzing DC voltage and current distribution on PCB power rails
Checking design rules (max current density, voltage margins, via current limits)
Discovering and listing power nets on an imported PCB layout
Assigning source/load/sense topology for PDN analysis
Running batch analysis across multiple power rails on a board
Inferring nominal voltage from standard PCB net naming conventions
When NOT to Use
Importing PCB layouts (Gerber, ODB++, Allegro) — use
matlab-read-pcb-layoutAnalyzing S-parameters, fields, or EM performance — use
matlab-analyze-emAnalyzing crosstalk between signal traces — use
matlab-design-pcb-transmission-lineDefining dielectric or conductor materials — use
matlab-manage-pcb-materialModeling via structures — use
matlab-model-via
Typical Workflow
Before:
matlab-read-pcb-layout— import the PCB layout from Gerber/ODB++/AllegroThis skill: Run DC analysis, check IR drop, evaluate design rules, batch-analyze nets
After: Iterate on the physical design in CAD and re-import, or use results to inform stackup changes via
matlab-manage-pcb-material
Quick Reference
| Task | Code |
|---|---|
| Import PCB layout | pcb = pcbFileRead('board_native') |
| List all nets | netList = cadnetList(pcb) |
| Find power nets | Filter cadnetList(pcb) with regexpi (see below) |
| Find specific rail | idx = ~cellfun(@isempty, regexpi(netList.CadnetName, "P0V8")) |
| Infer rail voltage | Parse net name with regex helper parseNetVoltage (see below) |
| Create cadnet | cnet = cadnet(pcb, 'P0V8') |
| Show cadnet layout | show(cnet) |
| Find components on net | comps = findComponents(cnet) |
| Filter by type | inductors = findComponents(cnet, "ComponentType", "Inductor") |
| Create PDN model | PDN = powerDistributionNetwork(cnet) |
| Assign topology | setNetworkParameters(PDN, Source=src, Load=load, Sense=sense) |
| Auto-assign topology | setNetworkParameters(PDN, AutoAssignDefault='True') |
| Set DC parameters | setDCParameters(PDN, "NominalVoltage", 0.8, "LoadCurrent", 1) % placeholder — ask user |
| Set DC rules | setDCRules(PDN, "MaxCurrentDensity", 0.5, "MinVoltage", 0.784) |
| Voltage distribution | voltage(PDN) |
| Voltage with violations | voltage(PDN, ShowViolation=true) |
| Current distribution | current(PDN) |
| Current with arrows | current(PDN, Direction='on') |
PCB Import and Net Discovery
Importing a PCB Layout
pcbFileRead imports a PCB file and returns an object for hierarchical inspection. Supported formats: native directory (CSV files), ODB++ (zipped or unzipped), and Cadence Allegro .brd (requires one-time extractaSetup()).
% Native format (directory containing CSV files)
pcb = pcbFileRead(fullfile(boardDir, 'pcie5_native'));
% ODB++ format
pcb = pcbFileRead(fullfile(boardDir, 'myboard.zip'));
% Allegro .brd (run extractaSetup() once first)
extractaSetup(); % one-time setup for Allegro support
pcb = pcbFileRead(fullfile(boardDir, 'myboard.brd'));The returned object exposes: NumLayers, NumCadnets, NumPadStacks, NumComponents, NumParts, LayerHeight.
Listing All Nets
NetList = cadnetList(pcb);
disp(NetList);Returns a table with columns: CadnetIdx, CadnetName, NumPins, Length. A real board may have 3000+ nets.
Finding Power Nets
There is no built-in findPowerNets function. Filter the cadnetList output using regex to identify power and ground nets by name:
netList = cadnetList(pcb);
% Define naming patterns (case-insensitive)
powerPatterns = ["^P\d+V", "^VDD", "^VCC", "^AVDD", "^DVDD", "^VDDO"];
groundPatterns = ["^GND", "^AGND", "^DGND", "^PGND", "^VSS", "^AVSS", "^DVSS"];
% Match power nets
isPower = false(height(netList), 1);
for p = powerPatterns
isPower = isPower | ~cellfun(@isempty, regexpi(netList.CadnetName, p));
end
powerNets = sortrows(netList(isPower, :), 'NumPins', 'descend');
% Match ground nets
isGround = false(height(netList), 1);
for g = groundPatterns
isGround = isGround | ~cellfun(@isempty, regexpi(netList.CadnetName, g));
end
groundNets = sortrows(netList(isGround, :), 'NumPins', 'descend');
% Filter by minimum pin count
minPins = 5;
powerNets = powerNets(powerNets.NumPins >= minPins, :);
% Search for a specific pattern (e.g., 0.8V rails)
idx = ~cellfun(@isempty, regexpi(powerNets.CadnetName, "P0V8"));
rails_0v8 = powerNets(idx, :);Common power net naming conventions (case-insensitive):
Power rails:
P<digit>V<digit>(P0V8, P3V3_AUX, P12V),VDD*,VCC*,AVDD*,DVDD*,VDDO*Ground nets:
GND*,AGND*,DGND*,PGND*,VSS*,AVSS*,DVSS*
Inferring Rail Voltage from Net Name
There is no built-in inferRailVoltage function. Parse voltage from net names using regex:
function nomV = parseNetVoltage(netName)
netName = string(netName);
% Pattern: P<int>V<frac> (e.g., P0V8 → 0.8, P3V3 → 3.3, P12V → 12.0)
tok = regexp(netName, '(?i)P(\d+)V(\d*)', 'tokens');
if ~isempty(tok)
intPart = str2double(tok{1}{1});
fracStr = tok{1}{2};
if isempty(fracStr)
nomV = intPart;
else
nomV = intPart + str2double(fracStr) / 10^numel(fracStr);
end
return;
end
% Pattern: explicit decimal (e.g., 3.3V, 1.8V)
tok = regexp(netName, '(\d+\.\d+)\s*V', 'tokens');
if ~isempty(tok)
nomV = str2double(tok{1}{1});
return;
end
% Pattern: millivolt (e.g., 800MV → 0.8)
tok = regexp(netName, '(\d+)\s*MV', 'tokens', 'ignorecase');
if ~isempty(tok)
nomV = str2double(tok{1}{1}) / 1000;
return;
end
nomV = NaN;
endUsage in a loop:
for k = 1:height(powerNets)
netName = powerNets.CadnetName{k};
nomV = parseNetVoltage(netName);
fprintf('%s → %.2f V\n', netName, nomV);
endcadnet Object
Creating a Cadnet
cnet = cadnet(pcb, 'P0V8');Properties:
| Property | Description |
|---|---|
NumPins | Number of pins on the net |
NumSurfaces | Number of copper surfaces |
NumVias | Number of vias |
NumTraces | Number of traces |
TotalLength | Total trace length |
EntityList | List of all entities |
Voltage | Nominal voltage |
LayerRange | Layers spanned by the net |
Visualizing a Cadnet
show(cnet);Finding Connected Components
findComponents returns a table with columns: Refdes, PinList, ComponentType, Part.
% All components on the net
allComps = findComponents(cnet);
% Filter by component type
inductors = findComponents(cnet, "ComponentType", "Inductor");
ics = findComponents(cnet, "ComponentType", "IC");
resistors = findComponents(cnet, "ComponentType", "Resistor");
caps = findComponents(cnet, "ComponentType", "Capacitor");The Refdes values are strings -- use them directly for Source/Load/Sense assignment in setNetworkParameters.
Getting Detailed Cadnet Data
data = cadnetData(cnet);
s = shapes(cnet);powerDistributionNetwork Object
Creating a PDN Model
PDN = powerDistributionNetwork(cnet);Properties:
| Property | Description |
|---|---|
NetType | Type of net |
Source | Source component(s) |
Load | Load component(s) |
Sense | Sense component(s) |
PlatingThickness | Via barrel plating thickness (inches) |
NominalVoltage | Nominal voltage (V) |
LoadCurrent | Load current (A) |
MaxCurrentDensity | Max current density (mA/mil²) |
MinVoltage | Minimum allowable voltage (V) |
MaxVoltage | Maximum allowable voltage (V) |
MaxViaCurrent | Max via current (mA) |
PDN Configuration
setNetworkParameters -- Assign Source, Load, Sense, Plating
Use findComponents output to assign topology:
% Manual assignment using RefDes from findComponents
setNetworkParameters(PDN, ...
Source=sourceRefDes, ...
Load=sinkRefDes, ...
Sense=senseRefDes, ...
PlatingThickness=0.002);
% Auto-assign defaults (fallback when topology is unclear)
setNetworkParameters(PDN, AutoAssignDefault='True');Source -- RefDes of the power source (typically an inductor). Use all inductors for multiphase rails.
Load -- RefDes of the load (typically an IC). Use all ICs on the net.
Sense -- RefDes of the sense component (typically a resistor or test point).
PlatingThickness -- Via barrel plating thickness in inches (e.g.,
0.002= 2 mil ≈ 1.4 oz copper).
Sense Component Resolution
The Sense parameter is required. When no test point is available on the net, use a resistor as the sense component:
tp = findComponents(cnet, 'ComponentType', 'Test Point');
if ~isempty(tp)
senseRef = tp.Refdes;
else
res = findComponents(cnet, 'ComponentType', 'Resistor');
senseRef = res.Refdes(1); % use first resistor as sense fallback
end
setNetworkParameters(PDN, Source=src, Load=load, Sense=senseRef, ...
PlatingThickness=0.002);Multiphase Rails
For multiphase VRM designs, multiple inductors feed the same rail. Always use all inductors as Source, not just the first:
inductors = findComponents(cnet, "ComponentType", "Inductor");
setNetworkParameters(PDN, Source=inductors.Refdes); % handles multiphasesetDCParameters -- Set Electrical Parameters
setDCParameters(PDN, "NominalVoltage", 0.8, "LoadCurrent", 1); % placeholder — ask user for actual valuesetDCRules -- Set DC Design Rules
setDCRules(PDN, ...
"MaxCurrentDensity", 0.5, ...
"MaxVoltage", 0.816, ...
"MinVoltage", 0.784, ...
"MaxViaCurrent", 500);DC rules units (mixed — specific to this API):
| Property | Units | Description |
|---|---|---|
PlatingThickness | inches | Via barrel plating thickness (0.002 = 2 mil) |
NominalVoltage | V | Nominal rail voltage |
LoadCurrent | A | Expected load current per sink |
MaxCurrentDensity | mA/mil² | Current density thermal limit |
MinVoltage | V | Minimum allowable absolute voltage |
MaxVoltage | V | Maximum allowable absolute voltage |
MaxViaCurrent | mA | Max current through a single via |
Voltage tolerance guidelines:
| Rail Voltage | Tolerance | MinVoltage | MaxVoltage |
|---|---|---|---|
| < 1 V | 1–2% | P0V8: 0.8 × 0.98 = 0.784 V | 0.8 × 1.02 = 0.816 V |
| 1–3.3 V | 2–3% | P1V8: 1.8 × 0.975 = 1.755 V | 1.8 × 1.025 = 1.845 V |
| 3.3–5 V | 3–5% | P3V3: 3.3 × 0.97 = 3.201 V | 3.3 × 1.03 = 3.399 V |
DC Analysis
Voltage Distribution
voltage(PDN);
% Show design rule violations
voltage(PDN, ShowViolation=true);Current Distribution
current(PDN);
% Show current direction arrows
current(PDN, Direction='on');Inspecting PDN Configuration Before Analysis
Check the PDN model properties after setup to verify assignments:
PDN.Source
PDN.Load
PDN.Sense
PDN.NominalVoltage
PDN.LoadCurrentWorkflow: Single-Net PDN Analysis
Interactive workflow for analyzing one power net end-to-end:
%% Step 1: Import the board
pcb = pcbFileRead(fullfile(boardDir, 'pcie5_native'));
%% Step 2: Identify power nets
netList = cadnetList(pcb);
powerPatterns = ["^P\d+V", "^VDD", "^VCC", "^AVDD", "^DVDD"];
isPower = false(height(netList), 1);
for p = powerPatterns
isPower = isPower | ~cellfun(@isempty, regexpi(netList.CadnetName, p));
end
powerNets = sortrows(netList(isPower, :), 'NumPins', 'descend');
disp(powerNets);
%% Step 3: Create cadnet and inspect
cnet = cadnet(pcb, 'P0V8');
show(cnet);
%% Step 4: Discover components for topology assignment
allComps = findComponents(cnet);
inductors = findComponents(cnet, "ComponentType", "Inductor");
ics = findComponents(cnet, "ComponentType", "IC");
resistors = findComponents(cnet, "ComponentType", "Resistor");
%% Step 5: Resolve voltage from net name
nomV = parseNetVoltage('P0V8'); % 0.8 V (see helper function above)
%% Step 6: Create and configure PDN
PDN = powerDistributionNetwork(cnet);
setNetworkParameters(PDN, ...
Source=inductors.Refdes, ...
Load=ics.Refdes, ...
Sense=resistors.Refdes(1), ...
PlatingThickness=0.002);
setDCParameters(PDN, "NominalVoltage", nomV, "LoadCurrent", 1); % placeholder — ask user for actual value
tolerancePct = 0.02; % 2% for <1V rails
setDCRules(PDN, ...
"MaxCurrentDensity", 0.5, ...
"MaxVoltage", nomV * (1 + tolerancePct), ...
"MinVoltage", nomV * (1 - tolerancePct), ...
"MaxViaCurrent", 500);
%% Step 7: Run analysis
voltage(PDN, ShowViolation=true);
current(PDN, Direction='on');Workflow: Multi-Net Batch Analysis
For batch analysis of all power rails on a board (loop with skip logic, per-rail spec tables), see references/batch-analysis.md.
Common Patterns
Component Refdes Usage
findComponents returns Refdes as a string -- use directly in setNetworkParameters. Use all matching components, not just the first:
inductors = findComponents(cnet, "ComponentType", "Inductor");
setNetworkParameters(PDN, Source=inductors.Refdes); % all inductorsWhen to Use AutoAssignDefault
Use AutoAssignDefault='True' only when:
No inductors found on the net (LDO rails, connector-fed rails)
User explicitly requests automatic topology assignment
Quick screening mode where accuracy is secondary
Always prefer explicit findComponents-based assignment.
Z-Axis Visualization
Use daspect to see Z-axis detail in 3D views:
ax = gca;
daspect(ax, [1, 1, 0.05]);Pitfalls
inferRailVoltagereturnsNaNfor unrecognized nets. Guard withisnan()before using the result in calculations or display (e.g.,string(NaN)produces"NaN", notmissing).Senseparameter is required insetNetworkParameters. When no test point exists on the net, use a resistor as the sense component. OmittingSensewill cause errors during analysis.AutoAssignDefaultis a fallback, not a first choice. It may produce incorrect topology assignments on complex rails (LDO, connector-fed). Prefer explicit assignment viafindComponentsoutput.LoadCurrentcannot be inferred from board data — STOP and ask. UnlikeNominalVoltage(which can be parsed from net names), load current must come from IC datasheets or system power budgets. Before callingsetDCParameters, ask the user for the actual load current and STOP execution — do not proceed until the user responds. Do NOT assume 1 A or any default without explicit user confirmation. Once the user responds that they don't have it or asks you to proceed, present these estimation options and let them choose:Per-pin heuristic: 0.5 A × number of load pins (e.g., 130 pins → 65 A)
TDP-based: total power budget ÷ rail voltage (e.g., 40 W ÷ 0.8 V = 50 A)
Fixed conservative: 10 A per load IC (quick screening)
1 A token: minimal value to verify the workflow runs end-to-end
Only after the user selects an option or provides a value, proceed with
setDCParameters.LoadCurrentmust be a vector, not a scalar total. When multiple load ICs exist on a rail,setDCParametersrequires one current value per load. For example, with loads U1 (4.8 A) and U9 (0.2 A):setDCParameters(PDN, LoadCurrent=[4.8, 0.2]). Passing a scalar (e.g.,LoadCurrent=5) errors when the topology has more than one load.PDN units are mixed — not all SI.
PlatingThicknessis in inches (not meters):0.002= 2 mil ≈ 1.4 oz copper.MaxCurrentDensityis mA/mil² (not A/mm²).MaxViaCurrentis mA (not A).MinVoltage/MaxVoltageare absolute volts. Using meters for plating (e.g.,35e-6) or amps for via current (e.g.,1) produces wildly incorrect results.Batch mode: skip rather than block. When a rail is missing voltage, source, or load information, skip it and report which rails were skipped and why. Do not halt the entire batch for one incomplete rail.
Large boards have 3000+ nets.
cadnetListreturns all nets. Filter with regex onCadnetNameto narrow to power/ground nets, then further filter byNumPinsor specific patterns.cnet.Voltageis unreliable. TheVoltageproperty on the cadnet object is populated heuristically from the PCB file and often returns'0.000'even for valid power rails. Always parse the voltage from the net name using regex instead of relying on this property.No built-in
findPowerNetsorinferRailVoltage. These do not exist as MATLAB functions. UsecadnetList(pcb)+regexpifiltering for net discovery, and theparseNetVoltagehelper (defined in this skill) for voltage inference from net names..brdfiles require extracta — STOP if unavailable. If the user only has a.brdfile andextractaSetup()returns[]or errors, STOP and inform the user: extracta (from a Cadence install) is required. Offer alternatives: (a) provide the path toextracta.exe, (b) export from Allegro as ODB++ or native CSV format, (c) use a colleague's Cadence install to convert. Do not attempt workarounds.
Related Skills
matlab-read-pcb-layout-- Importing PCB/package layouts for PDN analysismatlab-manage-pcb-material-- Substrate and conductor material setupmatlab-model-via-- Via modeling for power delivery pathsmatlab-analyze-em-- EM analysis fundamentals
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md18.1 KiB
- manifest.yaml473 B
- references/batch-analysis.md4.3 KiB
ATTRIBUTION.md
Attribution
This folder is an unmodified copy of the Agent Skill "matlab-analyze-pcb-pdn", distributed by AutoGineer (https://autogineer.com/agent-skills).
Commit: 2a7f215e965597acf6ed495beb9e7b8aff45a3be
Created by: MathWorks (https://github.com/matlab/matlab-agentic-toolkit/tree/2a7f215e965597acf6ed495beb9e7b8aff45a3be/skills-catalog/rf-and-mixed-signal/matlab-analyze-pcb-pdn)
Publisher: MathWorks (https://github.com/matlab)
Licence: BSD 2-Clause License (https://github.com/matlab/matlab-agentic-toolkit/blob/2a7f215e965597acf6ed495beb9e7b8aff45a3be/LICENSE.md)
Licence evidence: repository licence LICENSE.md
Retrieved: 2026-11-07
The skill's own files are unmodified copies. AutoGineer is not affiliated with or endorsed by the author or the publisher.
Files added by AutoGineer
ATTRIBUTION.md: this file, written by AutoGineer
LICENSE: copied from LICENSE.md
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-analyze-pcb-pdn · 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-analyze-pcb-pdn.zip