关于 matlab-analyze-pcb-pdn
matlab-analyze-pcb-pdn 是用于 MATLAB 的 PCB 电源分配网络分析技能,面向检查电源轨直流电压、电流与设计规则的工程工作。它涵盖电源网发现、拓扑配置及单网或多网批量分析。
主要功能
- 01发现并筛选 PCB 电源网
- 02配置电源、负载和检测点
- 03计算电压与电流分布
- 04检查电压及电流密度规则
- 05批量分析多个电源轨
适用场景
- 01检查电源轨的 IR 压降
- 02定位超出电压限制的区域
- 03核查过孔电流和电流密度
- 04批量评估板上多个电源网
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-analyze-pcb-pdn安装后在 Claude Code 中输入/matlab-analyze-pcb-pdn确认已加载。
附带文件manifest.yamlreferences/batch-analysis.md
详细介绍
分析电源分配网络(PDN)
适用场景
- 分析 PCB 电源轨上的直流电压和电流分布
- 检查设计规则(最大电流密度、电压裕量、过孔电流限制)
- 发现并列出导入的 PCB 布局中的电源网络
- 为 PDN 分析分配源/负载/检测拓扑
- 对电路板上的多个电源轨运行批量分析
- 根据标准 PCB 网络命名约定推断标称电压
不适用场景
- 导入 PCB 布局(Gerber、ODB++、Allegro)——使用
matlab-read-pcb-layout - 分析 S 参数、场或电磁性能——使用
matlab-analyze-em - 分析信号走线之间的串扰——使用
matlab-design-pcb-transmission-line - 定义介质或导体材料——使用
matlab-manage-pcb-material - 对过孔结构建模——使用
matlab-model-via
典型工作流
- 之前:
matlab-read-pcb-layout——从 Gerber/ODB++/Allegro 导入 PCB 布局 - **此技能:**运行直流分析、检查 IR 压降、评估设计规则,并对网络进行批量分析
- **之后:**在 CAD 中迭代物理设计并重新导入,或使用结果指导通过
matlab-manage-pcb-material进行的叠层变更
快速参考
| 任务 | 代码 |
|---|---|
| 导入 PCB 布局 | pcb = pcbFileRead('board_native') |
| 列出所有网络 | netList = cadnetList(pcb) |
| 查找电源网络 | 使用 regexpi 过滤 cadnetList(pcb)(见下文) |
| 查找指定电源轨 | idx = ~cellfun(@isempty, regexpi(netList.CadnetName, "P0V8")) |
| 推断电源轨电压 | 使用正则表达式辅助函数 parseNetVoltage 解析网络名称(见下文) |
| 创建 cadnet | cnet = cadnet(pcb, 'P0V8') |
| 显示 cadnet 布局 | show(cnet) |
| 查找网络上的元件 | comps = findComponents(cnet) |
| 按类型筛选 | inductors = findComponents(cnet, "ComponentType", "Inductor") |
| 创建 PDN 模型 | PDN = powerDistributionNetwork(cnet) |
| 分配拓扑 | setNetworkParameters(PDN, Source=src, Load=load, Sense=sense) |
| 自动分配拓扑 | setNetworkParameters(PDN, AutoAssignDefault='True') |
| 设置直流参数 | setDCParameters(PDN, "NominalVoltage", 0.8, "LoadCurrent", 1) % placeholder — ask user |
| 设置直流规则 | setDCRules(PDN, "MaxCurrentDensity", 0.5, "MinVoltage", 0.784) |
| 电压分布 | voltage(PDN) |
| 显示违规项的电压 | voltage(PDN, ShowViolation=true) |
| 电流分布 | current(PDN) |
| 显示方向箭头的电流 | current(PDN, Direction='on') |
PCB 导入和网络发现
导入 PCB 布局
pcbFileRead 会导入 PCB 文件并返回一个对象,用于分层检查。支持的格式:原生目录(CSV 文件)、ODB++(压缩或未压缩)以及 Cadence Allegro .brd(需要一次性运行 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'));
返回的对象公开以下属性:NumLayers、NumCadnets、NumPadStacks、NumComponents、NumParts、LayerHeight。
列出所有网络
NetList = cadnetList(pcb);
disp(NetList);
返回一个包含以下列的表:CadnetIdx、CadnetName、NumPins、Length。实际电路板可能有 3000 多个网络。
查找电源网络
没有内置的 findPowerNets 函数。使用正则表达式筛选 cadnetList 的输出,根据名称识别电源和地网络:
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, :);
常见电源网络命名约定(不区分大小写):
- 电源轨:
P<digit>V<digit>(P0V8、P3V3_AUX、P12V)、VDD*、VCC*、AVDD*、DVDD*、VDDO* - 地网络:
GND*、AGND*、DGND*、PGND*、VSS*、AVSS*、DVSS*
根据网络名称推断电源轨电压
没有内置的 inferRailVoltage 函数。使用正则表达式从网络名称中解析电压:
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;
end
在循环中使用:
for k = 1:height(powerNets)
netName = powerNets.CadnetName{k};
nomV = parseNetVoltage(netName);
fprintf('%s → %.2f V\n', netName, nomV);
end
cadnet 对象
创建 Cadnet
cnet = cadnet(pcb, 'P0V8');
属性:
| 属性 | 描述 |
|---|---|
NumPins | 网络上的引脚数量 |
NumSurfaces | 铜表面的数量 |
NumVias | 过孔数量 |
NumTraces | 走线数量 |
TotalLength | 走线总长度 |
EntityList | 所有实体的列表 |
Voltage | 标称电压 |
LayerRange | 网络跨越的层 |
可视化 Cadnet
show(cnet);
查找连通组件
findComponents 返回一个包含以下列的表: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");
Refdes 值是字符串,可直接用于 setNetworkParameters 中的 Source/Load/Sense 赋值。
获取 Cadnet 详细数据
data = cadnetData(cnet);
s = shapes(cnet);
powerDistributionNetwork 对象
创建 PDN 模型
PDN = powerDistributionNetwork(cnet);
属性:
| 属性 | 描述 |
|---|---|
NetType | 网络类型 |
Source | 源组件 |
Load | 负载组件 |
Sense | 检测组件 |
PlatingThickness | 过孔孔壁镀层厚度(英寸) |
NominalVoltage | 标称电压(V) |
LoadCurrent | 负载电流(A) |
MaxCurrentDensity | 最大电流密度(mA/mil²) |
MinVoltage | 最低允许电压(V) |
MaxVoltage | 最高允许电压(V) |
MaxViaCurrent | 最大过孔电流(mA) |
PDN 配置
setNetworkParameters —— 赋值 Source、Load、Sense 和镀层厚度
使用 findComponents 的输出配置拓扑:
% 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(通常为电感)。对于多相电源轨,请使用所有电感。
- Load —— 负载的 RefDes(通常为 IC)。请使用网络上的所有 IC。
- Sense —— 检测组件的 RefDes(通常为电阻或测试点)。
- PlatingThickness —— 过孔孔壁镀层厚度,单位为英寸(例如,
0.002= 2 mil ≈ 1.4 oz 铜厚)。
检测组件解析
Sense 参数为必填项。如果网络上没有测试点,请使用电阻作为检测组件:
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);
多相电源轨
对于多相 VRM 设计,多个电感为同一电源轨供电。请始终将所有电感用作 Source,而不只是第一个:
inductors = findComponents(cnet, "ComponentType", "Inductor");
setNetworkParameters(PDN, Source=inductors.Refdes); % handles multiphase
setDCParameters —— 设置电气参数
setDCParameters(PDN, "NominalVoltage", 0.8, "LoadCurrent", 1); % placeholder — ask user for actual value
setDCRules —— 设置直流设计规则
setDCRules(PDN, ...
"MaxCurrentDensity", 0.5, ...
"MaxVoltage", 0.816, ...
"MinVoltage", 0.784, ...
"MaxViaCurrent", 500);
直流规则单位(混合单位——此 API 专用):
| 属性 | 单位 | 描述 |
|---|---|---|
PlatingThickness | 英寸 | 过孔孔壁镀层厚度(0.002 = 2 mil) |
NominalVoltage | V | 电源轨标称电压 |
LoadCurrent | A | 每个负载端的预期负载电流 |
MaxCurrentDensity | mA/mil² | 电流密度热限制 |
MinVoltage | V | 最低允许绝对电压 |
MaxVoltage | V | 最高允许绝对电压 |
MaxViaCurrent | mA | 单个过孔允许通过的最大电流 |
电压容差指南:
| 电源轨电压 | 容差 | 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 |
直流分析
电压分布
voltage(PDN);
% Show design rule violations
voltage(PDN, ShowViolation=true);
电流分布
current(PDN);
% Show current direction arrows
current(PDN, Direction='on');
分析前检查 PDN 配置
设置完成后,检查 PDN 模型属性以验证赋值:
PDN.Source
PDN.Load
PDN.Sense
PDN.NominalVoltage
PDN.LoadCurrent
工作流:单网络 PDN 分析
用于端到端分析单个电源网络的交互式工作流:
%% 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');
工作流:多网络批量分析
有关对电路板上的所有电源轨进行批量分析(包含跳过逻辑循环和逐电源轨规格表),请参阅 references/batch-analysis.md。
常见模式
组件 Refdes 的用法
findComponents 返回的 Refdes 为字符串,可直接用于 setNetworkParameters。请使用所有匹配的组件,而不只是第一个:
inductors = findComponents(cnet, "ComponentType", "Inductor");
setNetworkParameters(PDN, Source=inductors.Refdes); % all inductors
何时使用 AutoAssignDefault
仅在以下情况使用 AutoAssignDefault='True':
- 在网络上找不到电感(LDO 电源轨、由连接器供电的电源轨)
- 用户明确要求自动分配拓扑
- 准确性不重要的快速筛查模式
始终优先使用基于 findComponents 的显式分配。
Z 轴可视化
使用 daspect 查看 3D 视图中的 Z 轴细节:
ax = gca;
daspect(ax, [1, 1, 0.05]);
注意事项
-
inferRailVoltage对无法识别的网络会返回NaN。 在计算或显示结果前,使用isnan()进行保护(例如,string(NaN)会生成"NaN",而不是missing)。 -
setNetworkParameters要求提供Sense参数。 如果网络上没有测试点,请使用电阻作为检测元件。省略Sense会导致分析出错。 -
AutoAssignDefault是后备方案,而非首选。 对于复杂电源轨(LDO、由连接器供电),它可能会产生错误的拓扑分配。优先使用findComponents的输出进行显式分配。 -
无法从电路板数据推断
LoadCurrent——请停止并询问。 与可以从网络名称解析的NominalVoltage不同,负载电流必须来自 IC 数据手册或系统功率预算。调用setDCParameters前,请询问用户实际负载电流,并停止执行——在用户回复前不要继续。 未经用户明确确认,不要假定为 1 A 或任何默认值。用户回复说没有该值或要求继续后,再提供以下估算选项并让其选择:- 按引脚估算: 每个负载引脚 0.5 A(例如,130 个引脚 → 65 A)
- 基于 TDP 估算: 总功率预算 ÷ 电源轨电压(例如,40 W ÷ 0.8 V = 50 A)
- 固定保守值: 每个负载 IC 取 10 A(用于快速筛查)
- 1 A 占位值: 用于确认工作流能够端到端运行的最小值
只有在用户选择某个选项或提供数值后,才能继续调用 setDCParameters。
-
LoadCurrent必须是向量,不能是标量总值。 当电源轨上存在多个负载 IC 时,setDCParameters要求每个负载提供一个电流值。例如,负载 U1(4.8 A)和 U9(0.2 A):setDCParameters(PDN, LoadCurrent=[4.8, 0.2])。当拓扑中有多个负载时,传入标量(例如LoadCurrent=5)会报错。 -
PDN 的单位混用——并非全部采用 SI 单位。
PlatingThickness的单位是英寸(不是米):0.002= 2 mil ≈ 1.4 oz 铜厚。MaxCurrentDensity的单位是 mA/mil²(不是 A/mm²)。MaxViaCurrent的单位是 mA(不是 A)。MinVoltage/MaxVoltage是绝对电压,单位为伏特。电镀厚度使用米(例如35e-6)或过孔电流使用安培(例如1),都会导致结果严重错误。 -
批处理模式:跳过,而不是阻塞。 如果某条电源轨缺少电压、电源或负载信息,请跳过该电源轨,并报告跳过了哪些电源轨以及原因。不要因为一条信息不完整的电源轨而中止整个批处理。
-
大型电路板有 3000 多个网络。
cadnetList会返回所有网络。使用CadnetName上的正则表达式过滤以缩小到电源/接地网络,然后进一步按NumPins或特定模式过滤。 -
cnet.Voltage不可靠。 cadnet 对象的Voltage属性是根据 PCB 文件启发式填充的,即使是有效的电源轨,也经常返回'0.000'。始终使用正则表达式从网络名称解析电压,不要依赖此属性。 -
没有内置的
findPowerNets或inferRailVoltage。 这些并非 MATLAB 函数。使用cadnetList(pcb)+regexpi过滤来发现网络,并使用此技能中定义的parseNetVoltage辅助函数从网络名称推断电压。 -
.brd文件需要 extracta——如果不可用,请停止。 如果用户只有.brd文件,且extractaSetup()返回[]或报错,请停止并告知用户:必须使用 extracta(来自 Cadence 安装)。提供以下替代方案:(a) 提供extracta.exe的路径;(b) 从 Allegro 导出为 ODB++ 或原生 CSV 格式;(c) 使用同事的 Cadence 安装进行转换。不要尝试变通方案。
相关技能
matlab-read-pcb-layout-- 导入 PCB/封装布局以进行 PDN 分析matlab-manage-pcb-material-- 设置基板和导体材料matlab-model-via-- 为电源传输路径建立过孔模型matlab-analyze-em-- 电磁分析基础
版权所有 2026 The MathWorks, Inc.