Core concepts & tutorials

核心思路:geometry-first

klink 不试图“从文字一键生成整版图”。它的核心方法是 geometry-first:几何(手绘的或生成的)在先,你在几何上标注意图(Port 与 Anchor),然后 routing 算法据此把布线补全,最后用结构化几何查询和 live LVS 判定完成。人保留 GUI 自由,agent 负责读、写、搬运、录制、路由和验证真实几何。

geometry-first 核心思路

传统参数化版图工具(如基于 stretch handle 的 PCell)默认形状是矩形——拉一条边就等于一个参数 W。CMOS 全是方块,这招管用。但光子学、柔性电子、MEMS、超导电路的形状不是方块:渐变 taper、弧形弯曲、自由拓扑,没有“拉那条边 = 参数”这种一一对应。

klink 走另一条路:轻量语义标注(lightweight semantic annotation),而不是完备约束系统。你在自己确定的几何位置上标记意图,routing 算法补全被标记之间的部分;不满意就补标、再跑。这是一个可迭代收敛的过程,不是一次性黑箱生成。两类标记:

Port

连接意图(net endpoint)

klink_Port PCell,携带 net + 朝向 + 宽度。它回答“这里要连出一条属于某网络的线,朝哪个方向、多宽”。

Anchor

路由约束(routing constraint)

klink_Anchor PCell,kind 为 waypoint_region / bend_region / corridor。它回答“线应该经过这里 / 在这里弯 / 走这条通道”。

这两者就是路由后端的输入:先 mark Port + Anchor,再调一个 routing.* 工具,几何布线由算法生成。这条边界让 klink 的机制层保持工艺无关——所有工艺事实(层、尺寸、间距)都由你在调用时显式传入。

Port:连接意图

Port 标记一个网络端点。它是一个 klink_Port PCell,参数就是唯一权威数据源(center / orientation / width / target_layer / port_type / net)——三角朝向标记和文字标签由 PCell 自动生成,永远不会和参数漂移。routing 后端默认从 999/99 层读取 Port 标记。

port.mark cell="NET1" name="A" center_um=[0,0]   orientation="E" width_um=2 net="sig"
port.mark cell="NET1" name="B" center_um=[80,20] orientation="W" width_um=2 net="sig"
port.list cell="NET1"

命名对齐 gdsfactory 习惯(方向名 E0/N0/W0/S0、类型名 o1/e1)。你在 GUI 里画的三角/矩形也能被吸附固化成标准 Port——通过方向推断 + 就近真实边吸附(贴边容差、45° 栅格回退)。Port 由不可变 name 标识,可以 update / transform(含按 GUI 选择批量改)/ unmark;重复或空名可以用 port.repair_names 修复。完整工具见 MCP 参考 · Port 与 Anchor

Anchor:路由约束

Anchor 表达“线要怎么走”。默认从 999/1 层读取。三种 kind

kind几何与语义
waypoint_region矩形必经区域——线必须穿过它。
bend_region三角形,取其内切圆作为弯曲搜索区——线在这里做圆弧/折角过渡。
corridor折线定义的方向性通道:线要“进入 → 沿方向走 → 离开”,不是简单穿过。普通 corridor 必经;标 choice_group=BUS 后变成 routing.global_channel_cell可选负载均衡候选通道。
anchor.mark cell="NET1" kind="waypoint_region" center_um=[40,40] radius_um=6 net="sig"

Anchor 与 Port 共享同一套身份模型:id/name 定位、label 显示、net 连接语义三者分离,重复/空 id 可以用 anchor.repair_ids 修复。这套“薄插件只做增删改、厚客户端负责理解手绘标记”的分工是有意为之——如何解读一个标记属于会持续演化的 workflow 逻辑,不该固化进 KLayout 插件。

Keepout 不是 anchor 类型。 避障是你传给 routing 工具的 obstacle_layers——你自己设计里的 keepout 层。klink 不带默认 keepout 层(900/0 是保留 keepout 层,structdevice 内部把它当 scratch 用)。

标记 → 路由 → 验证

geometry-first 的最简完整流程:

1 · 几何手绘或生成器件/焊盘几何。
2 · 标意图port.mark + anchor.mark。
3 · 路由routing.* 生成布线几何。
4 · 验证结构化报告 + live LVS。
port.mark cell="NET1" name="A" center_um=[0,0]   orientation="E" width_um=2 net="sig"
port.mark cell="NET1" name="B" center_um=[80,20] orientation="W" width_um=2 net="sig"
anchor.mark cell="NET1" kind="waypoint_region" center_um=[40,40] radius_um=6 net="sig"
routing.tapered_hybrid_cell cell="NET1" angle_mode="manhattan" obstacle_layers=["900/0"]
# 检查结果:ok=true、obstacle_hit_count=0、无 sibling overlap

路由后端按拓扑/质量分工(tapered hybrid 为主、tapered polygon 连续 taper、steiner 多端、damped 更强避让、global channel 全局决策、multilayer escape 跨层逃逸、gdsfactory 策略)。逐个见 MCP 参考 · 路由后端。多后端拒绝“一个万能路由器”:它们共享同一套 Port/Anchor 规划器,输出差异是“表达形式不同”而非“质量分级”。

几条贯穿路由层的设计原则:

  • 零栅格化几何路由。 用可见性图 + Dijkstra,产生完美直线段而不是锯齿,天然支持 0/45/90° 角度模式;不依赖 klayout.db
  • Port 出线契约。 路由器不能把 Port 当任意点——必须沿 orientation 从 center 发射再进入全局寻路;会造成回折时加一个垂直小 dogleg,而不是静默改写 Port 方向。
  • 结果必须自证。 ok / obstacle_hit_count / sibling overlap / route_count 是结构化质量门;零匹配不等于成功。参数无法被所选后端满足时会报错并点名哪些后端支持它,绝不静默忽略。
  • 诚实汇报边界。 global channel 明确“不是完整的拆线重布拥塞路由器”;multilayer escape 不建模过孔包围盒;gdsfactory 的 astar 不可靠,klink 会二次校验、穿墙则主动报错。

用户项目模型

klinkklink_plugin机制层(安装的包,永远不改)。你的工艺、器件、尺寸、层号、DRC/LVS 规则都留在用户项目里,显式传给机制层。

your-project/
  pdk.py          你的工艺——工艺事实唯一的家
  custom_devices/ agent 或你写的 device generator / flow 脚本
  specs/          .klink 规格、net table、交互意图
  out/            生成的 GDS / 结果(切勿提交 GDS)
  AGENTS.md       agent 规则(CLAUDE.md 指向它)
  mcp.example.json
用户项目绝不包含 GDS/PDK 内容——无论专有 foundry PDK 还是器件版图。模板 .gitignore 默认拦 *.gds/*.oas。让 recipe 代码在运行时指向这些文件(开放 PDK 可依赖,同样不提交)。

创建项目

用打包进 wheel 的 CLI 脚手架一个项目,再用 agent 打开它。

klink init my-chip
cd my-chip

描述你在做什么,agent 识别领域后从匹配的 recipe 脚手架 pdk.py + 第一条 custom_devices/ 脚本,并把你的工艺显式传进 klink。没有硬编码默认项目——新项目要先明确 domain 和 geometry tier 才开始生成。

升级 klink 之后,用 klink update mychip(或在项目目录内直接 klink update)刷新 example_template/ 里的 starter demo;你自己的 pdk.pycustom_devices/.klink/out/specs/ 绝不会被覆盖:

python -m pip install -U klayout-klink
klink update mychip

选择 recipe

recipe 是某个领域的参考实现。geometry tier 说明它需不需要你的机密几何。

领域几何层级公开 release 状态
EBL nanodeviceSelf-contained离线可跑,示例内自带参数。
Neural electrode harnessSelf-contained需 live KLayout,公开示例用 Port/Anchor PCell + tapered-hybrid router。
Silicon photonicsOpen or your own公开 feature 用开放 gf.gpdk(需装 gdsfactory);换成你的 PDK 即路由你的。
Digital P&R → LVSSelf-contained or your ownfit-device demo 用合成 exemplar;换成你真实器件几何来拟合并布线。Verilog→gates 需外部 yosys,缺失时流程返回确切修复命令。

新领域=一个为它塑形的 pdk.py + 一个 custom_devices/ 脚本(import 你的工艺、显式调 klink API)。复制最近的目录条目改写即可,你从不编辑 klink 来加领域

图文分步教程

下面是 7 篇分步图文教程,全部对应 example_template/ 里可以直接跑的 starter 示例(其中 digital 家族两篇需要 live KLayout 会话):教程与示例是同一个实体的两个视图,每篇教程对应一个示例脚本,把它拆成可观察的阶段,每一步在 live KLayout 里真的画出来、截图,并配上产生它的 klink 调用,最后用结构化报告(而不是截图)判定完成;教程结尾就是那条能直接复制运行的一键命令。建议按顺序读——后一篇会复用前一篇建立的概念。逐个 demo 的功能/依赖/实测数字见 示例

入门 · nanodevice

Hall bar 器件

geometry-first 的完整入门流程:画 mesa/接触/pad,标 Port + Anchor 意图,一次调用路由 fanout,用路由报告验证。纯离线合成器件,需 live KLayout。

看分步教程 →
EBL · writefield

EBL wraparound 纳米器件

写场(writefield)约束下的手工布线:keepout 边界、允许穿越窗口(corridor Anchor)、拼接 patch 补偿,以及事后补标 Port/Anchor 的场景。

看分步教程 →
批量 RPC · 参数化

神经电极阵列 harness

--elec-rows 参数化生成,394 个几何对象靠 shape.insert_many 批量写入;键合 pad 到电极之间近 8 倍尺度落差,走廊 Anchor 强制汇聚后一次批量路由 24 个 net。

看分步教程 →
硅光 · gdsfactory

gdsfactory MZI 接管与拖动重布线

一次 import_gf_component 接管普通 gdsfactory 热光 MZI 脚本;GUI 里拖动任意组件后,同一个 photonics.reroute 调用只重新布线、不重建器件。需要 gdsfactory。

看分步教程 →
structdevice · 数字 P&R

自定义器件:拟合 → PCell → P&R → LVS

从几个不同尺寸的范例几何拟合出参数化边模型,注册成真 PCell,按网表摆放 173 个实例,FlexDR 详细布线,最后 live LVS match=True。starter,需 live KLayout 会话。

看分步教程 →
structdevice · padframe

针卡优先的 padframe

探针卡 / pad 环先固定,电路必须迁就它:pad 环 harvest、net→pad 分配、一半卡内一半卡下的摆放、分区电网,最后 card 与 --no-card 裸线头两种模式各自 live LVS match=True。starter,需 live KLayout 会话。

看分步教程 →
passives · 几何模板

无源器件几何模板

IDC 叉指电容、方形螺旋电感、SAW IDT 滤波器、BAW/FBAR 俯视图四族参数化几何模板,每族默认参数 + 变体参数各一张实跑截图。passives/ 类 starter,离线可跑,--live 推 KLayout。

看分步教程 →

离线器件教程

从完全离线的 EBL wraparound 或 Hall bar 开始最稳——它们展示“机制层不含工艺事实”:示例自带尺寸、层号和 writefield 规则,再调 klink.domains.nanodevice

klink init nano-demo
cd nano-demo
python example_template/nanodevice/ebl_wraparound.py
python example_template/nanodevice/hallbar.py

在仓库 checkout 里也可直接跑公开 gallery:

python -m examples_klink.public.demos.nanodevice.ebl_wraparound
python -m examples_klink.public.demos.nanodevice.hallbar

复制到你的项目后,先改参数、不改 klink/;参数稳定后再整理成 custom_devices/<device>.py。逐个 demo 详解见 示例

硅光示例(gdsfactory 桥接)

如果你已有 gdsfactory 代码,公开 checkout 里有两个相关示例:低层 feature(features/24_gdsfactory_route_ports.py30_gdsfactory_routing_zoo.py),和完整 demo demos/gf_mzi_module.py——把一个普通 gdsfactory MZI 脚本接管进 klink 的 reroute loop。

安装始终是一条命令pip install klayout-klink 就装好 klink 全部。这个示例额外需要同一个解释器里有 gdsfactory(klink 是 RPC client,几何由 gdsfactory 在客户端构建)——klink 不打包第三方库,缺了会提示你确切的 pip install[photonics] 不是“按领域安装”,只是把一个测试过的 gdsfactory 一并装上的便捷写法:

pip install "klayout-klink[photonics]"    # = klink + 一个已测试的 gdsfactory
klink init my-chip && cd my-chip
python example_template/photonics/gf_mzi_module.py --port <session-port>
# 仓库克隆里也可以: python -m examples_klink.public.demos.photonics.gf_mzi_module --port <session-port>

接管后,在 KLayout GUI 里拖动组件,一次 photonics.reroute 同时重路由光学和金属——细节见 工作流 · 8082 klive 显示MCP 参考 · 硅光。从普通 shell 重新布线用 --reroute flag,它只从拖动后的位置重路由、不重建

python example_template/photonics/gf_mzi_module.py --port <session-port> --reroute

换成你的 PDK 时,层、stub 规则、cross-section 都来自你的脚本或 pdk.py

P&R 到 LVS

公开 release 的 digital path 是自包含或用户自带几何两种模式。fit-device demo 用合成 exemplar 跑通 device fit、placement、routing 和 live LVS。整个 digital 家族(fit-device、padframe、chat-to-netlist、multilayer)都是 example_template/digital/ 里的 starter,需要一个运行中的 KLayout 会话:

python example_template/digital/fit_device_pnr_lvs.py --port <session-port>
# 仓库克隆里也可以: python -m examples_klink.public.demos.digital.fit_device_pnr_lvs --port <session-port>

器件无关的自定义器件流由 structdevice.* 一族提供:给器件级网表 → build_from_netlist 自动 floorplan/route/draw/LVS;或 SEND 驱动的 declare_netsconnect_netslvs_checkspec_write。任何 LVS mismatch 都会撤销全部改动。

验证习惯

klink 教程不把截图当完成依据。判定用:

  • layout.infocell.treelayer.list 查结构。
  • shape.queryinstance.queryselection.get 查几何。
  • routing report 的 ok、overlap、obstacle hit、route count。
  • live LVS 的 match=True

一个路由/版图只有在 live KLayout LVS 返回 match=True 时才算“完成”;marker 计数和“看起来连上了”都不算。截图可以向人展示结果,但不能替代结构化验证。