把Gerber变成电磁波:推荐一款基于Gerber的openEMS仿真工具 - gerber2ems

描述

 画完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 的使用,可以参考:

OpenEMS:免费开源的电磁场求解器

gerber2ems 是一个 Python 脚本,旨在使用开源工具简化信号完整性 (SI) 仿真流程。它接收 PCB 生产文件(Gerber钻孔文件叠层信息)作为输入,并使用 openEMS 来仿真走线的信号完整性性能。openEMS 是一款免费开源的电磁场求解器,采用 FDTD (时域有限差分) 方法:

https://github.com/thliebig/openEMS-Project/

安装

安装 OpenEMS

安装以下软件包 (在 Debian/Ubuntu 上):

  •  
  •  
  •  
  •  
sudo apt updatesudo 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 一同测试过的最新版本。

  •  
  •  
  •  
  •  
  •  
  •  
git clone https://github.com/thliebig/openEMS-Project.gitpushd ./openEMS-Projectgit checkout bb991bb3git submodule update --init --recursive./update_openEMS.sh ~/opt/openEMS --pythonpopd

安装 gerber2ems 脚本

1. 安装依赖:

  •  
  •  
sudo apt install gerbv python3.11 pipxpipx ensurepath

2. 克隆并安装 gerber2ems:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
git clone https://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

要仿真一条走线,请遵循以下步骤:

  1. 准备输入文件并将它们放入 fab/ 文件夹 (详见PCB 输入文件准备部分)。

  2. 准备配置文件 simulation.json (详见配置准备部分)。

  3. 运行 gerber2ems -a (过程详见几何结构创建部分)。

  4. 在 ems/results 目录中查看结果 (详见结果部分)。

  5. 运行 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 (PosXWidth/2,PosX+Width/2) (PosY,PosY+Length) 沿 Y 轴
90 (PosXLength,PosX) (PosYWidth/2,PosY+Width/2) 与 X 轴相反
180 (PosXWidth/2,PosX+Width/2) (PosYLength,PosY) 与 Y 轴相反
270 (PosX,PosX+Length) (PosYWidth/2,PosY+Width/2) 沿 X 轴
  • 文件示例:

  •  
  •  
# Ref     Val              Package                PosX       PosY       Rot  SideSP1       Simulation_Port  Simulation_Port      3.0000    11.7500  180.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 倍) (单位:微米)。

  • impedance - 端口的端接阻抗 (驱动器或接收器的阻抗) (单位:欧姆)。

  • layer - 端口所在的铜层编号 (从顶部开始计数)。

  • plane - 微带线参考平面所在的铜层编号 (从顶部开始计数)。

  • excite - 仿真器是否应将此端口用作输入端口 (对于多个激励端口,它们将在单独的仿真中被激励)。

差分对/走线

differential_pairs/traces 是被仿真信号的列表。每个信号可以有以下字段:

  • start_pstop_pstart_nstop_n - 用于信号的端口号 (差分对)。

  • startstop - 用于信号的端口号 (单端走线)。

  • 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 中查看仿真数据,请遵循以下步骤:

  1. 运行 gerber2ems -a --export-field

  2. 运行 ems2paraview

 是一个仿真的端口号,在 simulation.json 中定义,要列出所有可用端口,请使用:ems2paraview -l

dump locations 可以省略 ,或者你可以从以下列表中选择一个或多个关键字:

  • outer - 在板表面上方 100 微米处转储场

  • cu-outer - 在外部铜层的 Z 坐标位置转储场

  • cu-inner - 在内部铜层的 Z 坐标位置转储场

  • substrate - 在每个介电层的中间转储场

--oversampling  - 可以添加此项以增加导出场的频率 (通常 OpenEMS 每几百个时间步转储一次 Field) ( 默认值为 4)。

警告 

Field 导出文件可能轻易占用数百 GB 的存储空间。

动画

要生成动画,按以下步骤操作:

  1. 生成一个 PCB 的 blend 模型 (参见 picknblend:https://antmicro.github.io/picknblend/quickstart.html)

  2. 使用 --export-field 标志并增加过采样率 (--oversampling 16) 运行 gerber2ems 

  3. 将生成的 *.vtr 文件转换为灰度 png 图片 (运行 ems2png)

  4. 在 blender 中打开 PCB 的 blend 文件,并附加 EMS_Plane (File>>Append..>>EMS_Plane.blend/Object/EMS_Plane)

  5. 设置平面尺寸 (它应与切片大小大致相同)

  6. 进入 Shading (着色) 工作区

  7. 在左侧的每个纹理节点中,点击文件夹图标并选择第三步生成的编号最小的 png (例如,第一条走线使用 simulation_images/e_field_0_0000,第二条使用 simulation_images/e_field_1_0000)。

  8. 如果动画只需要显示一条走线,用一个设置为黑色的 RGB 节点替换掉另一个纹理节点。

  9. 在纹理节点上,将源类型从 Single Image (单个图像) 更改为 Image Sequence (图像序列),并用相应走线生成的图像数量更新 Frames (帧数) 字段。

  10. 将视图模式设置为 rendered (渲染),并将 EMS_Plane 定位在 PCB 纹理上相应走线的正上方 (你可能需要切换到一个场较强且覆盖大部分走线的帧)。

  11. 选择 EMS_Plane 并在图像序列的第一帧和最后一帧应用任意类型的关键帧。

  12. 在 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验证时,不妨让它帮你省下几千刀软件费!  
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分