SAED32 PDK 装载与验证 —— 变更 SOP¶
- 主题:把 Synopsys 大学计划 SAED32(32/28nm)EDK 装载进集群 NFS,并纳入 module 体系
- 执行日期:2026-09-29
- 交付物目录:
synopsys_pdk_saed32_20260929/(本文档位于docs/) - 实现体:
main.py/deployer.py(配套utils/与artifacts/)
1. 背景¶
集群已有 Synopsys 2018 批次工具(VCS/Verdi/DC/PT/ICC2/Formality/StarRC/HSPICE 等,
见项目根 docs/HANDOFF.md)与在线 license 服务,但没有任何可用于数字全流程的工艺库:
/pdk 下仅有 FreePDK15/FreePDK45/ncsu-cdk 等学术工艺,无法支撑综合、时序、仿真、
物理实现的真实跑通。
SAED32_EDK(19G,8 个库:stdcell rvt/lvt/hvt、sram、sram_lp、io_std、io_sp、pll)
此前放在操作机工程目录 /home/rain/Documents/eda_tools_ins/Synopsys/SAED32_EDK,
尚未进入共享存储,七台节点看不到、也无法通过 module 引用。
触发条件:需要一套七台节点一致可用、可被 module 引用、且经工具实测跑通的工艺库。
2. 目标¶
变更完成后应达到以下可验证状态:
/data/nfs/pdk/SAED32_EDK存在,属主root:root,目录 0755 / 文件 0644,内容与源树一致(17742 文件 / 9603 目录 / 19G)。/data/nfs/modulefiles/pdk/saed32/1.0.lua存在,module load pdk && module load saed32后得到PDK=saed32、PDK_ROOT=/pdk、SAED32_PATH=/pdk/SAED32_EDK。- 七台节点(31.28 + 六台 work)无需任何变更即可读到该库(经既有
/pdkro 挂载)。 - 工具级实测通过:DC 综合、PT 时序、VCS 仿真、ICC2 读库四件套在 31.28 上跑通。
- 重复执行装载
deploy命令零变更、全跳过(幂等)。
3. 前置条件¶
以下每一条都已落为可执行检查(precheck 子命令,作为 deploy/verify 的门禁第一步)。
| # | 条件 | 检查方式 | 级别 |
|---|---|---|---|
| 1 | 操作机为 NFS 服务端(192.168.31.249),/data 可用空间 ≥ 25G |
df -PB1 /data(按字节解析) |
BLOCK |
| 2 | /data/nfs/pdk 存在且已写入 /etc/exports |
test -d + grep -E '^/data/nfs/pdk[[:space:]]' /etc/exports |
BLOCK |
| 3 | 操作机有 rsync |
rsync --version |
BLOCK |
| 4 | 源树存在且非空 | test -d + find -type f -print -quit |
BLOCK |
| 5 | 当前身份为 root,或免密 sudo -n 可用 |
sudo -n true |
BLOCK |
| 6 | 七台节点 SSH 免密可达、身份 root、Rocky 9.x | 逐台 hostname / id -u / cat /etc/os-release |
BLOCK |
| 7 | 七台已挂载 /pdk 与 /opt/modulefiles |
mountpoint -q |
BLOCK |
| 8 | 31.28 已挂载 /tools |
mountpoint -q /tools |
BLOCK |
| 9 | license 端口可达(工具验证需要) | /dev/tcp/192.168.31.29/2700 |
WARN |
| 10 | 调度器上有作业的节点不动 | Slurm/LSF 查询 | BLOCK |
预检查实测(2026-09-29 01:44):BLOCK 0 项 / WARN 0 项 / INFO 58 项。
4. 影响范围¶
- 变更主机 1(数据):操作机
192.168.31.249(NFS 服务端)——写入/data/nfs/pdk/SAED32_EDK与/data/nfs/modulefiles/pdk/saed32/1.0.lua。 - 变更主机 2(系统包):
192.168.31.28(工具级验证节点)——幂等安装make、gcc(VCS 编译所需;实测其原本缺失)。只作用于nodes.tools组。 - 验证主机:7 台 ——
192.168.31.28(工具级验证)+.18/.19/.20/.25/.26/.27(库可见性抽查)。六台计算节点不做任何变更(/pdk为 ro 挂载,新增目录对其立即可见)。 - 是否停服:否。不改服务、不改 fstab/exports、不重启任何单元。
- 窗口期:无特定要求。落盘为纯新增,不覆盖既有 PDK;
/data为本地盘,写 19G 期间不影响 NFS 上其他导出的正常读写(实测写速约 117 MB/s,全程约 3 分钟)。 - 在跑作业:本次不触碰计算节点配置,调度器作业不受影响;工具级验证在 31.28(交互节点)执行,占用少量 CPU。
- 磁盘增量:
/data由 578G 增至约 597G(+19G),剩余约 1.2T。
5. 分步操作¶
实现体:
main.py(子命令precheck/deploy/drift/verify)。 下列命令与实现体等价,供阅读、复核与手工复现;幂等与错误处理由实现体保证,不在代码块里展开。
步骤 1:门禁预检查(只读)¶
在做任何变更前证明环境与配置合格。检查项覆盖第 3 章全部前置条件,
并输出 reports/precheck-<时间戳>.md。全部只读(mountpoint / df / grep / SSH 探测)。
cd synopsys_pdk_saed32_20260929
.venv/bin/python main.py --config config/pdk.yaml precheck
预期:结论:BLOCK 0 项,退出码 0。有 BLOCK 则终止,不进入后续步骤(--dry-run 下降级为告警)。
步骤 2:预演(零改动)¶
.venv/bin/python main.py --config config/pdk.yaml --dry-run deploy
预期:输出待变更项清单(首次为 sync_tree + write_modulefile),不产生任何落盘;
清单落盘为 reports/plan-<时间戳>.yaml。核对该清单与实际预期是否一致。
步骤 3:数据落盘(高危:写入 19G + 整树改属主)¶
做什么:把源树同步到 NFS 导出目录,并统一属主与权限。 为什么这么写:
--no-owner --no-group让 rsync 不比对属主:源文件属rain:rain,目标要求root:root, 若让 rsync 接管属主会在每次预演时判定"仍有差异",幂等判据永远不收敛;属主改由chown -R单独负责。--chmod=D755,F644把权限差异一并收进 rsync 判据,避免"内容一致但权限漂移"漏检。- 目标目录是 NFS 导出根的子目录,属 root,故整体经
sudo -n提权执行;不使用sudo交互提示 (无 tty 时会挂住),提权可用性已在步骤 1 校验。
# 高危:新增 19G 数据并整树改属主(仅作用于 <dest_dir>,不使用通配删除)
sudo -n mkdir -p /data/nfs/pdk/SAED32_EDK
sudo -n rsync -rlptD --no-owner --no-group --chmod=D755,F644 \
/home/rain/Documents/eda_tools_ins/Synopsys/SAED32_EDK/ \
/data/nfs/pdk/SAED32_EDK/
sudo -n chown -R root:root /data/nfs/pdk/SAED32_EDK
预期:rsync 结束无报错;du -sh 显示 19G,find -type f | wc -l 为 17742。
失败判断:空间不足或中断 → 目标可能为半份数据;直接重跑步骤 3 即可(rsync 增量补齐),
无需先删除;若源树本身异常 → 见第 7 章。
步骤 4:写入 modulefile(高危:覆盖既有文件前自动备份)¶
做什么:把渲染后的 modulefile 落到 module 树,使七台节点可 module load。
坑(本次实测踩到,务必注意):
- modulefile 内不得再声明
family("eda_pdk")。家族标识由家族入口Core/pdk.lua声明; 若实体 modulefile 重复声明同族,Lmod 会判定家族冲突并自动卸载pdk入口, 连带撤销MODULEPATH与已设变量——表现为module load saed32之后SAED32_PATH为空。 既有pdk/sky130亦不声明 family,本工程保持一致。 - 模块名是
saed32,不是pdk/saed32。Core/pdk.lua会把/opt/modulefiles/pdk追加进MODULEPATH,此后模块名即相对该路径;正确加载序列是module load pdk && module load saed32。 - 目标属 root,须提权写入。实现体先在工程
logs/下生成暂存文件(普通用户可写), 再install -D提权安装到目标同目录的临时名,最后mv -f原子替换—— 避免module load读到半写文件。 - Lmod 目录缓存可能滞后(共享文件系统上常见)。若加载时报 unknown,
先试
module --ignore_cache avail;仍不可见则需清理客户端缓存或重登。
# 高危:覆盖前先备份(实现体自动完成并登记 backup/README.md)
sudo -n install -D -m 0644 -o root -g root \
<渲染后的 modulefile 暂存文件> \
/data/nfs/modulefiles/pdk/saed32/.1.0.lua.tmp
sudo -n mv -f /data/nfs/modulefiles/pdk/saed32/.1.0.lua.tmp \
/data/nfs/modulefiles/pdk/saed32/1.0.lua
预期:/data/nfs/modulefiles/pdk/saed32/1.0.lua 属主 root:root、权限 0644。
失败判断:Permission denied 说明未走提权 → 检查 sudo -n true 是否可用。
步骤 5:工具验证节点补齐系统包¶
做什么:在工具级验证节点(nodes.tools)幂等安装 make、gcc。
为什么:VCS 编译末期需用 make + 编译器构建 rmapats.so,实测该节点缺这两个包,
报 Failed to make rmapats.so。这是工具运行依赖,与 PDK 数据无关,但缺它则 VCS 用例无法验证。
坑:不同节点软件源配置不一致(31.28 为阿里云源,六台仍为国外官方 mirrorlist)。
实测六台 dnf install 卡在 Downloading Packages 十余分钟无进展——因此本步只作用于
工具验证节点,六台留作待办(见附录 B 第 2 条)。
# 幂等:已装即跳过(rpm -q 探测);加超时与重试避免镜像挂着不动
ssh root@192.168.31.28 'rpm -q make gcc || dnf --setopt=timeout=60 --setopt=retries=3 \
--setopt=minrate=1000 install -y make gcc'
预期:rpm -q make gcc 输出两个版本号。失败判断:仓库不可达 → 检查该节点软件源。
步骤 6:一次执行完成 3+4+5¶
.venv/bin/python main.py --config config/pdk.yaml deploy
预期:状态: success,随后自动跑第 6 章验证;退出码 0。
再次执行应输出 状态一致,无需变更,跳过备份与执行(状态: skipped,退出码 0)——这就是幂等验收。
6. 验证¶
6.1 变更完整性(本机 NFS 侧)¶
# 与源树逐项比对:输出为空即完全一致
.venv/bin/python main.py --config config/pdk.yaml drift
预期:## 无漂移:本机 NFS 侧与期望态一致,退出码 0。
# 属主与权限抽样核对(应输出 0 与 0)
find /data/nfs/pdk/SAED32_EDK \( ! -user root -o ! -group root \) | wc -l
find /data/nfs/pdk/SAED32_EDK \( -type d ! -perm 0755 -o -type f ! -perm 0644 \) | wc -l
6.2 七台节点库可见性¶
# 任取一台(或逐台执行)
ssh root@192.168.31.18 'bash -lc "
module load pdk && module load saed32
echo SAED32_PATH=\$SAED32_PATH
ls \$SAED32_PATH/lib/stdcell_rvt/db_ccs/saed32rvt_tt0p85v25c.db"'
预期:打印 SAED32_PATH=/pdk/SAED32_EDK 且文件存在。实测七台全部通过。
6.3 工具级验证(四件套 + 抽查)¶
.venv/bin/python main.py --config config/pdk.yaml verify
若需手工复现单个工具(以 DC 为例):
ssh root@192.168.31.28 'bash -lc "
module load synopsys && module load eda2018/1.0 && module load pdk && module load saed32
cd /tmp/pdk_saed32_verify/dc_synth
dc_shell -f synth.tcl"'
预期:各用例输出 PDK_VERIFY_OK。结果报告落盘 reports/tools-verify-<时间戳>.md,
各用例末段输出留档于 reports/verify-logs/。
实测结果(2026-09-29,报告见 reports/tools-verify-<时间戳>.md):
| 用例 | 工具 | 结果 |
|---|---|---|
| dc_synth | DC 综合(读 saed32rvt_tt0p85v25c.db,出网表) |
✅ 通过 |
| pt_timing | PT 时序(读 .db + 读 DC 综合网表报时序) | ✅ 通过 |
| vcs_sim | VCS 仿真(编译 saed32nm.v + 最小激励) |
✅ 通过(见下:依赖 vcs-el7) |
| icc2_lib | ICC2 物理(.tf 建库 + LEF 参考库) | ✅ 通过 |
| libs_verify | 六台库可见性抽查 | ✅ 全部通过 |
VCS 用例的前置:Rocky 9 上 VCS 编译需加载独立模块
vcs-el7(el7 binutils +pthread_yieldshim)。该问题与 PDK 无关,已单独解决, 详见主题vcs_el7_binutils_20260929/docs/SOP.md。加载序列:module load synopsys && module load eda2018/1.0 && module load pdk && module load saed32 && module load vcs-el7
6.4 本次实测结论¶
- DC:以
saed32rvt_tt0p85v25c.db为 target/link library,read_verilog → link → compile跑通,映射出层次单元并写出网表pdktop_syn.v。 - PT:
read_db读入同一 .db(get_lib_cells可枚举单元),并读入 DC 网表完成时序分析。 - VCS:编译 SAED32 的 348 个标准单元模型并跑通最小激励,输出
PDK_VERIFY_OK(仿真打印AND2X1_RVT=1 OR2X1_RVT=1 INVX1_RVT=0)。 - ICC2:以
tech/milkyway/saed32nm_1p9m_mw.tf建库成功,标准单元以 LEF (lib/stdcell_rvt/lef/saed32nm_rvt_1p9m.lef)作为参考库读入并枚举成功。注:Milkyway 参考库路线不可用——ICC2 转换 Milkyway 需老 ICC 的
icc_shell(报LIB-090)。IC Compiler 介质已上传(synopsys2018/ic_compiler_vO-2018.06-SP1), 待安装后可切换该路线。 - 库可见性:七台(31.28 + 六台)
module load pdk && module load saed32后 关键文件test -r全部通过。
7. 回滚¶
备份位置¶
modulefile:覆盖前自动备份至backup/data/nfs/modulefiles/pdk/saed32/1.0.lua.bak.<时间戳>,并登记在backup/README.md。- 数据树:不做复制式备份——唯一来源是工程目录下的
SAED32_EDK/,可随时重新落盘。19G 复制两份无必要。
回滚步骤¶
# 1) 恢复 modulefile(幂等;无备份且目标不存在时视为无需回滚)
sudo -n .venv/bin/python main.py --config config/pdk.yaml --rollback
# 2) 删除数据树(不可逆,需显式 --force 确认;实现体先做安全判定:
# 必须位于 /data/nfs/pdk 之下、不等于导出根、目录名含 pdk.name)
sudo -n .venv/bin/python main.py --config config/pdk.yaml --rollback --force
手工等价命令(删除类操作路径写全,不用通配):
sudo -n rm -rf --one-file-system /data/nfs/pdk/SAED32_EDK
--one-file-system 可防止误删跨文件系统内容;路径已由实现体安全判定,不安全时拒绝执行。
回滚后验证¶
test -d /data/nfs/pdk/SAED32_EDK && echo 仍存在 || echo 已删除
ssh root@192.168.31.18 'bash -lc "module load pdk && module load saed32"' # 预期报错(模块已随文件移除)
8. 风险说明¶
| 风险 | 影响 | 缓解 |
|---|---|---|
/data 空间不足 |
落盘中断,留下半份数据 | 门禁校验可用空间 ≥ 25G(实测 1.16T 可用);中断后直接重跑,rsync 增量补齐 |
| 误删/误写非目标路径 | 破坏其他 PDK | 删除与属主修正前由实机事实判定:必须位于导出的 pdk 根之下、不等于该根、末段含 PDK 名;不满足即拒绝执行;删除用 --one-file-system |
| modulefile 家族冲突 | 加载后环境变量被撤销 | 实测定位并已规避(不声明 family);verify 用例包含加载后变量断言 |
| Lmod 缓存滞后 | module load 报 unknown |
文档给出 --ignore_cache 规避;客户端重登或清缓存可彻底刷新 |
| 工具级验证失败(老库 + 新工具兼容性) | 库可见但工具用不起来 | 结果按用例逐项记录;失败项写入交付说明与 HANDOFF 待办,不影响"库已可用"这一结论 |
| 落盘期间 NFS 客户端读到半份数据 | 工具读库报错 | 客户端 /pdk 为 ro 且本次为纯新增目录(SAED32_EDK 此前不存在),客户端不会读到中间态 |
附录¶
A. 交付物清单¶
| 路径 | 说明 |
|---|---|
main.py / deployer.py |
入口与编排(继承共享库 BaseModule) |
utils/config_validate.py |
配置合法性校验(五类) |
utils/pdk_state.py |
领域三态探测(rsync 差异 / 属主权限 / modulefile 摘要 / 导出条目 / 空间) |
utils/precheck.py |
领域预检查(继承共享库 PreCheckBase) |
utils/tool_verify.py |
工具级验证执行器与报告渲染 |
config/pdk.yaml |
站点配置(唯一真源) |
artifacts/modulefiles/saed32-1.0.lua.tpl |
modulefile 模板(单一源,渲染后写入 NFS) |
artifacts/{dc,pt,vcs,icc2}/ |
工具级验证用例 |
backup/ |
备份与台账(README.md 为登记表) |
reports/ |
预检查报告、变更清单、漂移报告、验证报告(19G 相关日志不落盘于仓库) |
B. 后续收敛项(本次未做,单独提出)¶
- ~~VCS 编译失败~~ 已解决(2026-09-29):解法是 el7 binutils 兼容层 + 独立模块
vcs-el7,见主题vcs_el7_binutils_20260929/docs/SOP.md;PDK 侧从无问题。 - 六台计算节点软件源:仍指向国外官方镜像(
mirrorlist→ nevacloud / krfoss 等),dnf install实测卡在 Downloading 十余分钟无进展;31.28 已切阿里云源。 本次未改六台软件源(属基础设施变更,应由存储/节点部署工程统一处理), 故六台未安装make/gcc——若要在六台上跑 VCS 仿真,需先统一换源再装包。 - 通用探测上移共享库:本工程
utils/pdk_state.py中的挂载点探测、license 端口探测, 与rocky9_eda_compat_20260928/utils/下的实现构成第二次实现,按共享库上移判据宜上移 (新增函数属非破坏性变更,但需回归全部挂载工程)。本次为控制变更面未做。 - pdk 家族纳入部署器声明:
slurm_ins/config/slurm_deploy.yaml的module_env.families目前只声明sky130。本工程的saed32为手工维护(与synopsys/eda2018/1.0.lua同模式), 部署器复跑不会删除它(只补缺失、不清理额外文件),但也不受其管理。 若希望纳入声明式管理,需给该项补 NFS 路径模型(现 family 的install_dir为节点本地路径语义)。 - ICC2 的 Milkyway 路线:如需用 Milkyway 参考库(而非 LEF),需补装老 ICC 的
icc_shell并设置lib.configuration.icc_shell_exec。
来源:
/home/rain/Documents/eda_tools_ins/Synopsys/synopsys_pdk_saed32_20260929/docs/SOP.md| 最后更新:2026-09-29 03:14(由build/sync.py同步,请勿在站点侧修改)