“画完PCB,打板之前,你是不是也心里打鼓:
“这根差分线到底90 Ω还是88 Ω?Stub 会不会把 5 GHz 信号打回原形?”
跑去借 50 GHz 网络分析仪?贵到哭。
用商业 SI 软件?授权费能再买一辆车。
别急,今天给你安利一个宝藏项目:gerber2ems,结合开源的 openEMS solver, 让你用家里电脑能跑 3D 全波 FDTD,直接看 S 参数、阻抗曲线,还带动画的那种!”

项目背景Antmicro 这帮老哥日常给 FPGA、RISC-V 板子做高速接口,信号完整性必须过关。可他们偏偏钟爱开源:KiCad 画板、openEMS solver。于是干脆写了 gerber2ems:把“Gerber + 钻孔+ 叠层”一键翻译成 openEMS 能吃的 3D 模型,跑完还能跟 VNA 实测对波。项目指路
GitHub地址:https://github.com/antmicro/gerber2emsLicense:Apache 2.0
关于 openEMS 的使用,可以参考:
gerber2ems 是一个 Python 脚本,旨在使用开源工具简化信号完整性(SI) 仿真流程。它接收 PCB 生产文件(Gerber、钻孔文件、叠层信息)作为输入,并使用openEMS来仿真走线的信号完整性性能。openEMS 是一款免费开源的电磁场求解器,采用FDTD(时域有限差分) 方法:
https://github.com/thliebig/openEMS-Project/
安装
安装 OpenEMS
安装以下软件包 (在 Debian/Ubuntu 上):
sudo aptupdatesudo apt install build-essential cmake git libhdf5-dev libvtk9-dev libboost-all-dev libcgal-dev libtinyxml-dev qtbase5-dev libvtk9-qt-dev cython3 pippip install--break-system-packages numpy scipy matplotlib h5py setuptools# 推荐使用此命令,因为 Debian 安装的 numpy 版本较旧,常导致版本冲突
克隆仓库、编译并安装openEMS。
建议使用bb991bb3这次提交 (commit),这是与 gerber2ems 一同测试过的最新版本。
gitclonehttps://github.com/thliebig/openEMS-Project.gitpushd./openEMS-Projectgit checkout bb991bb3git submodule update --init --recursive./update_openEMS.sh ~/opt/openEMS --pythonpopd
安装 gerber2ems 脚本
1. 安装依赖:
sudoapt install gerbv python3.11pipxpipxensurepath
2. 克隆并安装gerber2ems:
gitclonehttps://github.com/antmicro/gerber2ems.gitpushd./gerber2emspipx install --system-site-packages .popd
注意:如果你想使用ems2paraview命令,还需运行sudo apt install paraview python3-paraview。
你可以使用内置的示例来测试gerber2ems。这些示例是我们的开源硬件信号完整性测试板(https://openhardware.antmicro.com/boards/si-simulation-test-board/)的切片,使用KiCad SI wrapper生成。部分选定的示例在专用的vna.csv文件中包含了VNA(矢量网络分析仪) 的测量数据,这使我们能够将 openEMS 的仿真结果与真实世界的测量数据进行比较。
cd./gerber2ems/examples/stub_shortgerber2ems -a
使用方法
如需快速查阅,请使用gerber2ems --help。
要仿真一条走线,请遵循以下步骤:
-
准备输入文件并将它们放入
fab/文件夹 (详见PCB 输入文件准备部分)。 -
准备配置文件
simulation.json(详见配置准备部分)。 -
运行
gerber2ems -a(过程详见几何结构创建部分)。 -
在
ems/results目录中查看结果 (详见结果部分)。 -
运行
gerber2ems -a --export-field并使用Paraview查看电场动画 (详见Paraview部分)。
结果
下面展示了stub_short示例的仿真输出。该软件返回以下几类输出:
S 参数和阻抗数据
仿真过程中收集的阻抗和 S 参数数据,以带表头的 CSV 格式存储。
S 参数图表
每次激励期间测量的各 S 参数的图表。

史密斯圆图
每次激励的 S-11 参数图。

阻抗图表
每个激励端口的阻抗随频率变化的图表。

stub_short示例包含一个vna.csv文件,可用于验证仿真结果。

工作原理
项目准备
仿真整个 PCB 对资源消耗极大,因此,尽可能分离出一个小尺寸的感兴趣区域:不需要的走线、铺铜等都应移除。如果整个层都是多余的,你可以在后续步骤中移除它们。
应在坐标文件中使用虚拟元器件标记感兴趣的端口。其标号应以 "SP" 开头,后跟端口号。
钻孔文件的原点应置于左下角。
在现实中被端接且会存在于仿真中的每条走线或铺铜,都应使用仿真端口进行端接或连接到地。
目前,电容不参与仿真。对于高频仿真,可以用一条走线将其短路来近似处理。
PCB 输入文件准备
脚本需要多个输入文件来创建几何结构。这些文件都应位于 "fab" 文件夹中,具体如下:
-
Gerber 文件- 每个需要仿真的铜层都应有一个对应的 Gerber 文件,命名格式如下:
"<可选文本>-<来自叠层文件的名称>.gbr" -
叠层文件- 一个描述 PCB 叠层的文件,名为
stackup.json。格式示例:
{"layers":[{"name":"F.Cu","type":"copper","color":null,"thickness":0.035,"material":null,"epsilon":null,"lossTangent":null},{"name":"dielectric 1","type":"core","color":null,"thickness":0.2,"material":"FR4","epsilon":4.5,"lossTangent":0.02}],"format_version":"1.0"}
-
钻孔文件- Excellon 格式的带电镀通孔的钻孔文件。文件名应以
"-PTH.drl"结尾。 -
坐标文件- 描述端口位置的文件。文件名应以
"-pos.csv"结尾。-
坐标应相对于左下角给出。
-
端口的区域根据
simulation.json文件中的Width(宽度) 和Length(长度) 值,使用下表中的公式计算:
-
| 旋转 [°] | X 范围 | Y 范围 | 波传播方向 |
| 0 | (PosX−Width/2,PosX+Width/2) | (PosY,PosY+Length) | 沿 Y 轴 |
| 90 | (PosX−Length,PosX) | (PosY−Width/2,PosY+Width/2) | 与 X 轴相反 |
| 180 | (PosX−Width/2,PosX+Width/2) | (PosY−Length,PosY) | 与 Y 轴相反 |
| 270 | (PosX,PosX+Length) | (PosY−Width/2,PosY+Width/2) | 沿 X 轴 |
-
文件示例:
# Ref Val Package PosX PosY Rot SideSP1 Simulation_Port Simulation_Port 3.0000 11.7500180.0000 top
配置准备
simulation.json文件用于配置整个仿真过程。你可以在example_gerbers文件夹中找到示例文件。此文件中的所有尺寸单位均为微米 (micrometers)。该配置文件包含三个部分:
杂项
-
format_version- 指定配置文件的格式。编写新配置时,应使用最新的支持版本 (可在constants.py文件中查看)。 -
frequency-start指定了感兴趣的最低频率,stop指定了最高频率 (单位:Hz)。 -
max_steps- 仿真的最大步数,达到此步数后仿真将无条件停止。 -
pixel_size- 像素大小,单位为微米。用于 Gerber 转换 (默认值:5) (由于 libcairo 的限制,对于较大的板子需要增加此值,但应尽量保持其尽可能小)。 -
via/plating_thickness- 过孔电镀层厚度 (单位:微米)。 -
via/filling_epsilon- 过孔填充材料的介电常数。如果未填充,则应为 1。
网格
-
inter_layers- 相邻 PCB 层之间 Z 轴上的网格线数量 (默认值:4)。 -
optimal- 基本网格间距 (单位:微米) (用于金属边缘的单元) (默认值:50)。 -
diagonal- 网格间距 (单位:微米) (用于有对角线路径的区域) (默认值:50)。 -
perpendicular- 网格间距 (单位:微米) (用于路径与网格垂直的区域) (默认值:200)。 -
max- 最大网格间距 (单位:微米) (用于板区之外) (默认值:500)。 -
cell_ratio/xy- 最佳相邻单元尺寸比 (X/Y 轴) (默认值:1.2)。 -
cell_ratio/z- 最佳相邻单元尺寸比 (Z 轴) (默认值:1.5)。 -
margin/xy- X/Y 轴的边距大小 (单位:微米) (网格超出 PCB 的距离) (默认值:1000)。 -
margin/z- Z 轴的边距大小 (单位:微米) (默认值:1000)。 -
margin/from_trace- 根据感兴趣网络的边界框限制仿真空间 (默认值:True) (如果为 False,则使用板的边界框)。
网格间距选项应遵循:
optimal<=diagonal<=perpendicular<=max<=λmin/10端口
ports是一个端口列表。每个端口都有以下参数:
-
width- 端口宽度 (单位:微米)。 -
length- 端口长度 (端口目前由微带线片段组成,其长度应至少为网格单元尺寸的 8 倍) (单位:微米)。 -
layer- 端口所在的铜层编号 (从顶部开始计数)。 -
plane- 微带线参考平面所在的铜层编号 (从顶部开始计数)。 -
excite- 仿真器是否应将此端口用作输入端口 (对于多个激励端口,它们将在单独的仿真中被激励)。
差分对/走线
differential_pairs/traces是被仿真信号的列表。每个信号可以有以下字段:
-
start_p,stop_p,start_n,stop_n- 用于信号的端口号 (差分对)。 -
start,stop- 用于信号的端口号 (单端走线)。 -
name- 可选名称,用于识别信号。 -
nets- 在生成网格时要包含的网络列表 (例如["/CSI_A_CLK_N","/CSI_A_CLK_P"])。如果未指定,将使用netinfo.json文件中的数据。如果该文件也不存在,则在生成网格时会考虑所有网络 (GND除外)。
几何结构创建
这是一个通过-g标志启动的自动步骤。该脚本会定位创建几何结构所需的所有文件 (Gerber、钻孔文件、pnp 文件、叠层文件、仿真配置文件)。然后,它使用gerbv将 Gerber 文件转换为 PNG。接着,这些 PNG 被处理成三角形并输入到几何结构中。此过程还会添加过孔和端口的几何形状。所有物体都根据叠层文件放置在正确的 Z 轴高度上。
你可以使用AppCSXCAD(在安装 openEMS 时已安装) 查看生成的几何结构,它被保存在ems/geometry/geometry.xml文件中。
仿真
这是一个通过-s标志启动的自动步骤。该脚本会加载几何结构和配置文件。它将所有信息输入引擎并开始仿真,对每个激励端口进行迭代。
在这一步,用户应验证指定的时间步数是否足够。引擎建议它至少是脉冲长度的 3 倍:
```激励信号长度为: 3211 时间步 (3.18343e-10s)最大时间步数: 10000 ( --> 3.11429 * 激励信号长度)```
仿真器将几何结构转换为 voxels,并开始为网格中的每个边求解麦克斯韦方程组。它会执行一定数量的时间步 (在配置中指定的最大数量),然后退出。对于每个时间步,来自铜层之间平面的电场数据被保存到ems/simulation文件夹的文件中。端口电压和电流数据也会被保存。
在仿真过程中,其中一个端口使用高斯脉冲(具有宽带频率内容) 进行激励。这个脉冲穿过网络并从其他端口输出 (也可能辐射到板外)。
你可以通过查看引擎输出来监控仿真过程:
[@ 20s] 时间步: 4620 || 速度: 294.4 MC/s (3.372e-03 s/TS) || 能量: ~4.16e-16 (- 7.15dB)
通过这种方式,你可以看到:
-
当前处于哪个时间步
-
仿真器每秒处理多少网格体素
-
系统中剩余多少能量
在仿真过程中,能量应随着其通过端口离开而下降 (激励脉冲结束后),但由于不精确性和辐射能量,它不会降到 0。
仿真结束后,用户可以使用Paraview验证数据 (在下文的一个章节中描述)。
后处理
这是一个通过-p标志启动的自动步骤。该脚本会加载每个激励端口的仿真数据。然后,它进行FFT(快速傅里叶变换) 以获取频域数据。接着,它将入射波和反射波数据转换为阻抗和 S 参数。这些数据以 CSV 格式保存在ems/results/S-parameters文件夹中。这些数据也会被自动绘制成图表,图表保存在ems/results中。
Paraview
要在 Paraview 中查看仿真数据,请遵循以下步骤:
-
运行
gerber2ems -a --export-field -
运行
ems2paraview
是一个仿真的端口号,在simulation.json中定义,要列出所有可用端口,请使用:ems2paraview -l。
dump locations可以省略 ,或者你可以从以下列表中选择一个或多个关键字:
-
outer- 在板表面上方 100 微米处转储场 -
cu-outer- 在外部铜层的 Z 坐标位置转储场 -
cu-inner- 在内部铜层的 Z 坐标位置转储场 -
substrate- 在每个介电层的中间转储场
--oversampling - 可以添加此项以增加导出场的频率 (通常 OpenEMS 每几百个时间步转储一次 Field) (默认值为 4)。
警告
Field 导出文件可能轻易占用数百 GB 的存储空间。
动画
要生成动画,按以下步骤操作:
-
生成一个 PCB 的 blend 模型 (参见picknblend:https://antmicro.github.io/picknblend/quickstart.html)
-
使用
--export-field标志并增加过采样率 (--oversampling 16) 运行gerber2ems -
将生成的
*.vtr文件转换为灰度 png 图片 (运行ems2png) -
在blender中打开 PCB 的 blend 文件,并附加
EMS_Plane(File>>Append..>>EMS_Plane.blend/Object/EMS_Plane) -
设置平面尺寸 (它应与切片大小大致相同)
-
进入Shading(着色) 工作区
-
在左侧的每个纹理节点中,点击文件夹图标并选择第三步生成的编号最小的 png (例如,第一条走线使用
simulation_images/e_field_0_0000,第二条使用simulation_images/e_field_1_0000)。 -
如果动画只需要显示一条走线,用一个设置为黑色的 RGB 节点替换掉另一个纹理节点。
-
在纹理节点上,将源类型从Single Image(单个图像) 更改为Image Sequence(图像序列),并用相应走线生成的图像数量更新Frames(帧数) 字段。
-
将视图模式设置为rendered(渲染),并将
EMS_Plane定位在 PCB 纹理上相应走线的正上方 (你可能需要切换到一个场较强且覆盖大部分走线的帧)。 -
选择
EMS_Plane并在图像序列的第一帧和最后一帧应用任意类型的关键帧。 -
在
blendcfg.yaml中添加一个新的预设:
ems_animation:CAMERAS:PHOTO1: truePOSITIONS:TOP: trueRENDERER:FPS: 25SCENE:RENDERED_OBJECT: Object/EMS_PlaneOUTPUTS:- ANIMATION:
13. 运行pcbooth -b .blend -c ems_animation
提示
可以考虑创建一个新的 blend 文件,而不是直接使用picknblend的输出。在这个新文件中,将picknblend的输出作为链接的 blender 模型添加进来。这将允许你重复使用基础的 blender 模型来展示不同的走线仿真,并能防止gerber2blend/picknblend意外刷新模型。
结束语
虽然gerber2ems目前对复杂电源网络仿真支持有限,且大板子仍需高性能硬件支持,但它无疑为硬件开发者打开了信号仿真民主化的大门。下次做SI验证时,不妨让它帮你省下几千刀软件费!-
Gerber
+关注
关注
3文章
151浏览量
34822 -
电磁波
+关注
关注
21文章
1507浏览量
55994 -
仿真工具
+关注
关注
0文章
38浏览量
11401 -
KiCAD
+关注
关注
6文章
336浏览量
10591
发布评论请先 登录
Allegro 转Gerber 注意事项Gerber RS274D( 以Gerber6x00 为主)
怎么做GERBER文件?GERBER文件包含哪些内容?
怎么做GERBER文件?GERBER文件包含哪些内容?
gerber
Protel 99 SE转gerber文件步骤
ad09, gerber这个如何使用?
AD输出Gerber提示Gerber failed to match all shapes的解决
详解Altium Designer生成Gerber文件
Allegro轉Gerber注意事項
gerber文件是什么?gerber文件有哪些?
pcb如何生成gerber文件
把Gerber变成电磁波:推荐一款基于Gerber的openEMS仿真工具 - gerber2ems
评论