Case Study · structdevice · 数字 P&R

对话实战:自定义器件接进数字流程,跑到 LVS match

三句话,三轮真实调用:把一个合成器件的范例几何拟合成参数化 PCell、按网表摆放并详细布线、最后跑 live LVS 确认版图和网表完全一致。

这是一段真实对话记录。每句用户请求都是真实用户会说的话;针对每句,klink 的 AI agent 真的驱动了拟合→摆放→布线→LVS 的完整流程,在实时运行的 KLayout 里跑——截图和 LVS match、器件数都是本次真实运行的结果。
用户
我有同一个器件在几个不同尺寸下的画法(范例几何),帮我拟合成一个可任意改参数的 PCell。
klink agent

用你 4 个尺寸点的范例几何(合成背栅器件,W=10/50 µm × L=4/8 µm,两个参数轴都变过)跑拟合筛查:每条角色边做线性回归,分类成 linear(参数驱动)/ constant(不随参数动)/ unexplained(拟合器解释不了、需要你拍板)。筛查干净后出拟合表,注册成真 PCell(demobg),再画 3 个变体验证参数化是真的:dev10_8 是范例点本身,dev20_8 是 W 方向的插值,dev50_3 是 L 方向的外推(超出范例区间)。

pcell_fitter.analyze(exemplars=4, params=["w_um","l_um"]) → edges: 14 linear, 2 constant, 0 unexplained (16 条边全部有解释) pcell_fitter.fit_table(report, style="default", sample_order=[...]) pcell.register_fitted(name="demobg", fit_table=...) instance.insert_pcell_many(cell, [ dev10_8(w_um=10, l_um=8), # 范例点 dev20_8(w_um=20, l_um=8), # 插值 dev50_3(w_um=50, l_um=3), # 外推 ])
三个由同一 PCell 画出的器件变体,dev10_8、dev20_8、dev50_3,尺寸依次不同,橙色栅板、绿色源漏、网格状沟道
Turn 1 · 同一个 demobg PCell 在三组参数下的实例:拟合筛查 16 条边里 14 条 linear、2 条 constant、0 条 unexplained——参数化是拟合出来的,不是硬编码的。
用户
按一个小网表把这些器件摆放好,并做详细布线。
klink agent

网表是一个内置的 4-bit 加法器(62 个门、173 个器件实例、96 个网)。行列数和行距不是拍脑袋定的,是从这份网表推导出来的:62 个门 → 8×8 网格,行距按器件叠高 + 布线通道算出 170 µm。批量摆好 173 个拟合 PCell 实例后,把 96 个网里的信号网交给 FlexDR 详细布线器,在 3 层布线栈上走线;VDD/GND 走电源网格,不算在“信号网”里。

routing.grid.floorplan.derive_grid(gates=62) → rows=8, cols=8 routing.grid.floorplan.derive_row_pitch(...) → row_pitch_um=170.0 structdevice.layout_engine.place_grid(nl, rows=8, cols=8, profile, row_pitch) → 173 个器件实例 instance.insert_pcell_many(cell, 173 items) structdevice.layout_engine.route_and_draw_flexdr(cell, nl, placement, profile, layers=3, ...) → FlexDR 3.9s ok=True routed=94/94 markers=0 sig_vias=200 pdn_vias=166
8x8 器件阵列全部布通的整体视图,行间通道里布满横向绿色走线和纵向橙色、灰色走线,四周有电源环,顶部标 GND、底部标 VDD
Turn 2 · 173 个实例摆好,94/94 信号网全部布通、0 处 DRC 违例markers=0)。四周电源环带 GND/VDD 标签,走 166 个 PDN 过孔;信号网另走 200 个过孔跨层。
用户
跑 LVS,确认画出来的版图和网表连通完全一致。
klink agent

不是“看起来连上了”,是让 KLayout 原生的连通性提取器当裁判:从刚画好的真实几何里提取网络(金属层内连通 + 过孔跨层),和第二步声明的 96 个网逐一对账,再做 173 个器件的 netlist 比对。裁判读的连通性规则和布线器用的是同一份 profile 推导出来的,但提取本身是 KLayout 原生做的,不是布线器自己给自己打分。结果直接标注回版图,方便核对:

structdevice.lvs_check(cell, declared=96 nets, mode="lvsdb", connectivity=profile.connectivity_spec(), terminal_provider=geom_terminal_provider(...), placement=..., device_terms=...) → ok=True → device_lvs.match=True → device_lvs.device_count=173 shape.insert_text(cell, "LVS match=True devices=173", layer=6/0)

真实结果:match=True,173 个器件全部对上——版图里画出来的连通关系和网表声明的完全一致。

完成的 4-bit 加法器版图全景,底部有红色文字标注 LVS match=True devices=173
Turn 3 · LVS 通过后的成品全景。红色文字是 agent 写回版图的真实结果——LVS match=True devices=173,坐标取自这次摆放出来的版图边界,不是预先摆好的装饰。

想看这条链更完整、每一步都配拟合公式和局部放大细节的分步版本?看 自定义器件教程。DRC/LVS 的完整能力入口 → 指南 · DRC·LVS

如实复述:本页三轮对话用的器件几何、层号(101/0 栅板、103/0 沟道、104/0 源漏、106/0 布线、6/0 标注文字)、4-bit 加法器网表全部是为演示合成/内置的示例数据,不含任何真实工艺或客户数据;三次拟合/摆放/布线/LVS 调用和其返回的数字(14 linear + 2 constant 边、routed=94/94、markers=0、LVS match=True、devices=173)均对 live KLayout(专用会话,端口 8767)真实执行,截图为该次运行的真实渲染结果。工作用的一次性 tab 已在收尾时关闭,原有 tab 已恢复为当前视图,全程未触碰 8765/8766 上的任何会话。