PDK sky130A not found / PDK_ROOT not set:OpenLane 找不到 PDK 速查
更新时间:2026-10-25。FAQ 速查页,属于开源 EDA 排错系列。按 OpenLane Docker 安装实录 装好镜像、用 volare 拉了 sky130A,第一次跑
flow.tcl迎面就是一句sky130A not found——这不是 PDK 没下载,而是 OpenLane 根本不知道去哪个目录找。容器权限类的姊妹坑见 docker permission denied 速查。
答案块(赶时间先看这里)
- 报错原文:
[ERROR]: Failed to compare PDKs. /build/pdk/sky130A not found.(路径随你的环境而变) - 环境:Ubuntu 22.04,OpenLane 官方 Docker 镜像,PDK 由 volare 管理
- 根因:
PDK_ROOT环境变量没传进容器——OpenLane 退回默认路径/build/pdk,那里当然没有 sky130A - 修复:
export PDK_ROOT=$HOME/.volare(以 volare 实际落点为准),docker run 时加-e PDK_ROOT=$PDK_ROOT并挂载该目录 - 验证:log 开头出现
[INFO]: PDK Root: /home/ubuntu/.volare与[INFO]: Process Design Kit: sky130A即修复成功
本文要回答的问题
- 报错里的
/build/pdk/sky130A是哪来的?我明明没装过这个路径? - volare 下载的 PDK 落在哪?OpenLane 凭什么能找到它?
- 为什么在宿主机
echo $PDK_ROOT明明有值,进容器还是报 not found? - 修复后怎么确认 PDK 版本配对这关真的过了?
一、报错原文与现象
典型触发路径:volare 已经 volare enable 过 sky130A,宿主机上 PDK 明明躺在 ~/.volare/sky130A 里,但用官方镜像跑 flow.tcl,流程还没开始读设计就退出:
[ERROR]: Failed to compare PDKs.
/build/pdk/sky130A not found.
Traceback (most recent call last):
File "/openlane/dependencies/verify_versions.py", line 76, in verify_versions
raise Exception(f"{pdk_dir} not found.")
Exception: /build/pdk/sky130A not found.这张实录的关键在一行细节:报错路径是 /build/pdk/sky130A,而这条 docker run 是刻意用 env -u PDK_ROOT 抹掉变量后发起的——OpenLane 拿不到 PDK_ROOT 时不会问你,而是静默退回镜像里写死的默认落点 /build/pdk,在那里找不到 sky130A 就由 verify_versions.py 抛异常退出。看懂「报错路径 = 默认路径」这条线索,根因已经锁死:不是 PDK 丢了,是指路的环境变量没到位。
二、根因:PDK_ROOT 的四段解析链
OpenLane 找 PDK 走的是一条四层链路,任何一段断了都会在启动阶段报 sky130A not found:
颜色按角色分:蓝是你要动手的排查/配置动作,灰是容器内的中性状态,绿是 PDK 真实落点(修好后要对上的目标),橙是 OpenLane 内部的校验关卡,红是最终爆出的报错。读这张图抓住一条主线:报错发生在最末端的 verify 关卡,但断点可以在链路上任意一环——宿主机没 export、docker run 少 -e 或 -v、容器内路径拼错,表现一模一样,都是那句 not found。
值得多说的是报错里那段 Python traceback:抛异常的 verify_versions.py 是 OpenLane 启动时的「版本配对」关卡——它不只检查 PDK 目录存在,还要把 PDK 的版本号和 OpenLane 镜像内置的期望值比对,防止「镜像太新、PDK 太旧」跑出一堆莫名其妙的工艺规则错误。所以这一关报 not found 时,它连版本比对的机会都没有,直接在第一行断言上就倒了。这也解释了为什么这个报错总是出现在 log 最开头、STEP 1 综合之前:它是整个流程的第一道门禁。
三、三种常见来历对照清单
同样是 sky130A not found,背后有三种常见来历,判别和处置各不同:
| 场景 | 判别方法 | 处置 |
|---|---|---|
| PDK_ROOT 从没导出 | 宿主机 echo $PDK_ROOT 为空 | export PDK_ROOT=$HOME/.volare,写进 ~/.bashrc |
| volare enable 没跑过 | ls $PDK_ROOT/sky130A 不存在 | volare enable --pdk sky130 <版本号> 真正落盘 |
| 容器内外 HOME 错配 | 报错路径是 /root/.volare 而 PDK 在 /home/ubuntu/.volare | -v 把真实落点挂进容器、-e PDK_ROOT= 指向挂载后路径 |
第三种最阴:volare 按「当前用户的 HOME」落盘,用普通用户跑的 volare enable,PDK 在 /home/ubuntu/.volare;而 docker run 里如果随手写 -e PDK_ROOT=/root/.volare(容器默认 root 的 HOME),挂载又没覆盖,容器里那个目录就是空的——路径「看起来像那么回事」,实际差了一个用户。判别口诀:报错里的路径前缀必须和 volare 真实落点逐字符一致,不一致就是错配,不要猜。
还有一个容易混淆的变体:PDK_ROOT 在宿主机 export 了、docker run 也 -e 传了,但 -v 挂载只挂了 ~/.volare/sky130A 这一个子目录进容器,于是容器里 PDK_ROOT 指向的上级目录存在、sky130A 子目录却不在挂载覆盖范围内——路径对、内容空,报的还是同一句 not found。判别方法是在容器里直接看一眼:
docker run --rm -v $PDK_ROOT:$PDK_ROOT -e PDK_ROOT=$PDK_ROOT \
efabless/openlane:<tag> ls $PDK_ROOTls 输出里没有 sky130A,问题就锁在挂载这一环,不用再去怀疑 volare。这条「容器视角 ls」的预检思路在配置类报错里同样好用——先把「路径对不上」和「内容有问题」切开,再往下查,能省一半时间。
四、修复示例:export、传参、复跑
export PDK_ROOT=$HOME/.volare # 以 volare ls 显示的实际路径为准
ls $PDK_ROOT/sky130A # 先确认 PDK 真的在
docker run --rm \
-v /opt/openlane-src/OpenLane:/openlane \
-v $PDK_ROOT:$PDK_ROOT \ # 落点原样挂进容器
-v /path/to/design:/designs/small_counter \
-w /openlane \
-e PDK_ROOT=$PDK_ROOT -e PDK=sky130A \
efabless/openlane:<tag> ./flow.tcl -design /designs/small_counter -tag fix -overwrite要点是「同一路径三处对齐」:宿主机的 PDK_ROOT、-v 的挂载映射、-e 传进容器的值,三者拼出来的容器内路径必须恰好是 sky130A 的上级目录。挂载用「原样映射」(宿主机路径 = 容器路径)最不容易出错,省得脑子里再做一次路径翻译。
这张速查卡按语义分四色:红区是缺一即死的核心变量,蓝区是发起容器时的传参动作,紫区是 volare 侧的准备工作,绿区是修好后要在 log 里看到的确认信号。对照本次实录的修复 log:开头连续打出 PDK Root: /home/ubuntu/.volare、Process Design Kit: sky130A、Standard Cell Library: sky130_fd_sc_hd 三行,随后一路从 STEP 1 综合跑到 [SUCCESS]: Flow complete.,全程 42 个 STEP 无一中断——verify 这关过了,后面就是正常流程的事。修复前后唯一的差别就是 docker run 里多了 -v /home/ubuntu/.volare:/home/ubuntu/.volare 和 -e PDK_ROOT=/home/ubuntu/.volare 两组参数,成本一句话,收益是整条流程。
五、验证与防复发
修复后按顺序确认三件事:
echo $PDK_ROOT && ls $PDK_ROOT/sky130A/libs.ref # 落点真实存在且有标准库
volare ls --pdk sky130 # volare 视角确认已启用
# 复跑 flow.tcl,log 前 15 行应出现 PDK Root / Process Design Kit 两行 INFO三条全过,环境即干净,可进入 OpenLane 首次跑通流程。防复发纪律只有一条:把 export PDK_ROOT 写进 shell 启动文件,并在团队装机清单里把「volare enable + export」列为安装 OpenLane 的收尾动作,不要等 flow.tcl 报错了再回来补。多人共用服务器时再加一条:volare 统一用同一个服务账号落盘到公共路径(如 /opt/pdk),避免每个人 HOME 下各挂一份、容器映射各写各的——这类「HOME 错配」在多人环境里的出现频率远高于单机,写进清单比写进记忆可靠。
实验环境
- 机器/系统:云主机 / Ubuntu 22.04(eda-golden-v1 镜像)
- 工具版本:OpenLane d054702b(efabless/openlane 镜像),volare 管理 sky130A
- 日期:2026-10-24
- 完整命令:
env -u PDK_ROOT docker run --rm ... ./flow.tcl -design /designs/small_counter -tag c6_err -overwrite(复现报错);docker run --rm -v /home/ubuntu/.volare:/home/ubuntu/.volare -e PDK_ROOT=/home/ubuntu/.volare ... ./flow.tcl -tag c6_fix -overwrite(修复后完整复跑)
这一篇在知识体系里的位置
本篇是开源 EDA 排错簇中「环境变量/路径」节点的 FAQ 页,上承 OpenLane Docker 安装实录(安装阶段就该完成的 volare 落盘与 export),下接 OpenLane 首次跑通流程(PDK 门禁过了才轮得到设计配置);同类「连不上/找不到」的环境坑另见 docker permission denied(socket 权限)与 OpenLane OOM exit 137(内存不足),三者共享「先看报错原文里的路径、再查环境变量与挂载」的同一套方法论。
一句话总结
PDK sky130A not found / PDK_ROOT not set 的本质是 OpenLane 按「PDK_ROOT 环境变量 → docker -e/-v 传参 → 容器内路径 → volare 落点」四段链找 PDK,任一环节断链就在 verify 关报 not found(缺变量时静默退回 /build/pdk 默认路径);修复是让 export、挂载、传参三处路径逐字符对齐(export PDK_ROOT=$HOME/.volare + -v 原样映射 + -e 传入),log 开头打出 PDK Root: 与 Process Design Kit: sky130A 即修复,根治靠把变量写进 shell 启动文件与装机清单。