跳转至

VCS 在 Rocky 9 上的编译兼容层(el7 binutils)—— 变更 SOP

  • 主题:让 VCS(N-2017.12-SP2)在 Rocky 9 节点上能编译出 simv
  • 执行日期:2026-09-29
  • 交付物目录:vcs_el7_binutils_20260929/(本文档位于 docs/)
  • 实现体:deploy_el7_binutils.py(幂等;预演/执行/回滚)

1. 背景

SAED32 PDK 装载后做工具级验证(见 synopsys_pdk_saed32_20260929/docs/SOP.md), DC / PT / ICC2 均通过,VCS 用例失败。逐层排查后定位为两个叠加的兼容问题, 均与设计库无关(SAED32 的 348 个单元模型已被完整读入并编译):

  1. 新 binutils 拒绝 VCS 自带的预编译对象:

ld: archive.1/_xxxx_archive_1.a(amcQwB.o): .symtab local symbol at index 36 (>= sh_info of 2) ld: ... error adding symbols: bad value

Rocky 9 的 binutils 2.35 新增了符号表一致性严格校验;VCS 2017.12 随包的目标文件 是按老 binutils 语义生成的,CentOS 7 的 binutils 2.27 不校验、新版本校验。

  1. glibc ≥ 2.34 移除 pthread_yield:换用老 ld 后暴露 undefined reference to 'pthread_yield' (VCS 运行库 vcs_save_restore_new.o 引用它)。

排查中排除的方向:-nohsopt(被 VCS 判为非法选项);容器方案(历史已证 el7 容器因共享宿主内核同样不可行,见 vcs_runtime_20260928)。

关键前提:31.18 上已存在试点留下的兼容层 /opt/compat/(el7 binutils 2.27 与 libpthread_yield.so shim),当时未推广、也未被任何 module 引用。本次将其推广并固化。

2. 目标

  1. 七台节点(192.168.31.28 + 六台 work)的 /opt/compat/ 具备 el7 binutils 制品(11 个文件)。
  2. module 树新增独立入口 vcs-el7:加载后 ld 指向 el7 版本、LIBRARY_PATH/LD_LIBRARY_PATH 含 shim 目录。
  3. 用 SAED32 的真实模型跑通 VCS 完整链路(编译 → simv → 运行)。
  4. 重复执行 deploy_el7_binutils.py --apply 零变更、全跳过(幂等)。

3. 前置条件

# 条件 检查方式 级别
1 制品源(31.18)上兼容层文件齐备 逐个 test -f(脚本自动) BLOCK
2 七台 SSH 免密可达、身份 root hostname / id -u BLOCK
3 操作机可写 NFS module 树(root 或免密 sudo) sudo -n true BLOCK
4 节点 /opt/compat 目录可建 脚本 mkdir -p 幂等处理 —
5 make/gcc 已装(VCS 编译需要) rpm -q make gcc BLOCK

第 5 条已于本轮由 synopsys_mirror_switch_20260929 完成(七台均装)。

4. 影响范围

  • 变更主机:7 台 —— 192.168.31.28 与六台 work。写入 /opt/compat/{bin,lib64}(约 11 个文件、4 MB)。
  • 本机:写入 NFS module 树 /data/nfs/modulefiles/synopsys/vcs-el7/1.0.lua。
  • 是否停服:否。纯新增文件;不重启任何服务、不改 fstab/exports。
  • 对现有行为的影响:默认无影响——新模块需显式 module load vcs-el7 才生效; 未加载时 VCS 行为与变更前一致(即仍编译失败)。加载后该会话的 ld/ar/as 变为 el7 版本。
  • 在跑作业:不涉及。

5. 分步操作

实现体:deploy_el7_binutils.py。下列命令与实现体等价,供复核与手工复现。

步骤 1:预演

cd vcs_el7_binutils_20260929
../synopsys_pdk_saed32_20260929/.venv/bin/python deploy_el7_binutils.py

预期:列出各台待补齐文件数(31.18 应为「已一致,跳过」),并给出 modulefile 待写入计划。

步骤 2:写入 modulefile(先于节点验证)

各台验证依赖该模块已存在,故实现体先落 modulefile(覆盖前自动备份到 backup/)。

# 等价命令(渲染模板后原子替换;目标属 root)
sudo -n install -D -m 0644 -o root -g root <渲染后的 lua> \
  /data/nfs/modulefiles/synopsys/vcs-el7/.1.0.lua.tmp
sudo -n mv -f /data/nfs/modulefiles/synopsys/vcs-el7/.1.0.lua.tmp \
  /data/nfs/modulefiles/synopsys/vcs-el7/1.0.lua

坑:模块名是 vcs-el7(不是 synopsys/vcs-el7)——Core/synopsys.lua 会把 /opt/modulefiles/synopsys 加入 MODULEPATH,此后模块名即相对该路径,与 eda2018 同理。

步骤 3:分发兼容层制品

从制品源(31.18)取回 11 个文件,逐台比对 sha256:一致即跳过,否则先备份原文件再覆盖。

# 等价命令(以一台为例;<host> 为目标节点)
scp root@192.168.31.18:/opt/compat/bin/{ld,ar,as,nm,objdump,strip,ranlib} <host>:/opt/compat/bin/
scp 'root@192.168.31.18:/opt/compat/lib64/{libbfd-2.27-44.base.el7.so,libopcodes-2.27-44.base.el7.so,libpthread_yield.so,libpthread.so}' <host>:/opt/compat/lib64/
ssh <host> 'chmod 0755 /opt/compat/bin/{ld,ar,as,nm,objdump,strip,ranlib}'

预期:文件落位,sha256sum 与源一致。失败判断:SFTP 中断 → 重跑(幂等,已传部分跳过)。

步骤 4:一次执行 2+3

../synopsys_pdk_saed32_20260929/.venv/bin/python deploy_el7_binutils.py --apply

预期:逐台输出 GNU ld version 2.27-44.base.el7 | which=/opt/compat/bin/ld,退出码 0。 再次执行应全部「已一致,跳过」。

6. 验证

6.1 模块生效(逐台)

ssh root@192.168.31.18 'bash -lc "
  module load synopsys && module load vcs-el7
  ld --version | head -1; which ld"'

预期:GNU ld version 2.27-44.base.el7 + which=/opt/compat/bin/ld。七台实测均通过。

6.2 最小编译闭环(单台已实测)

ssh root@192.168.31.18 'bash -lc "
  module load synopsys && module load eda2018/1.0 && module load vcs-el7
  cd /tmp && printf \"module t; initial \\\$display(\\\"OK1\\\"); endmodule\n\" > x.sv
  vcs -full64 -sverilog x.sv -o simv && ./simv"'

预期:rc=0、生成 simv、运行输出 OK1。(31.18 上实测通过。)

6.3 SAED32 真实模型复验(关键闭环)

cd synopsys_pdk_saed32_20260929
.venv/bin/python main.py --config config/pdk.yaml verify

预期:vcs_sim 用例由 ❌ 转为 ✅(期望标识 PDK_VERIFY_OK)。 配置已把 vcs-el7 加入 tools_verify.module_load_cmd。

6.4 本次实测结论

验证项 结果
模块生效(七台) ✅ 均输出 GNU ld version 2.27-44.base.el7,which ld=/opt/compat/bin/ld
最小编译闭环(31.18) ✅ 编译 rc=0、生成 simv、运行输出 OK1
SAED32 真实模型闭环(31.28) ✅ rc=0,simv 1.2 MB,仿真输出 AND2X1_RVT=1 OR2X1_RVT=1 INVX1_RVT=0 与 PDK_VERIFY_OK

过程中额外发现的依赖:31.28 原缺 g++——VCS 最后一步用 g++ -o ../simv 链接, 缺它时报 make: g++: No such file or directory(Error 127)。已随 make/gcc 一并补齐, 七台现为 make + gcc + gcc-c++(由 synopsys_mirror_switch_20260929 幂等安装)。

结论:VCS 在 Rocky 9 上"编译不出 simv"的问题已解决——根因是 VCS 自带老目标文件 与新版 binutils 的不兼容(外加 pthread_yield 缺失),解法是 el7 binutils + shim, 与设计库、license、平台其余部分均无关。

7. 回滚

备份位置

  • 节点侧:覆盖前把原文件下载到 backup/<host>/opt/compat/…,并在 backup/README.md 登记。
  • modulefile:覆盖前备份到 backup/data/nfs/modulefiles/synopsys/vcs-el7/。

回滚步骤

# 1) 删除节点侧兼容层制品(逐台执行;仅删本主题新增的文件,不用通配)
ssh <host> 'rm -f /opt/compat/bin/{ld,ar,as,nm,objdump,strip,ranlib} \
                     /opt/compat/lib64/{libbfd-2.27-44.base.el7.so,libopcodes-2.27-44.base.el7.so,libpthread_yield.so,libpthread.so}'

# 2) 移除 module 入口
sudo -n rm -f /data/nfs/modulefiles/synopsys/vcs-el7/1.0.lua
sudo -n rmdir /data/nfs/modulefiles/synopsys/vcs-el7 2>/dev/null || true

回滚后验证

ssh root@192.168.31.18 'bash -lc "module load synopsys && module load vcs-el7"'   # 预期报模块不存在/守卫失败
ssh root@192.168.31.18 'which ld'                                                # 预期回到系统 /usr/bin/ld

8. 风险说明

风险 影响 缓解
el7 ld 无法链接新版 gcc 产物 加载该模块后,会话内所有编译走老工具链,可能失败 刻意做成独立 module(不并入 eda2018),只在编译 VCS 时加载,用完 module unload vcs-el7;模块 help 中已写明
老 ld/ar 覆盖系统工具 影响全机构建 只写入 /opt/compat/bin,不放进系统 PATH 的默认位置;仅靠 module 前置 PATH
shim 目录误入全局库路径 影响其他程序 LIBRARY_PATH/LD_LIBRARY_PATH 只在模块加载期间生效;不写 /etc/ld.so.conf.d/
制品来源不可信 引入异常二进制 制品来自本环境 31.18 既有试点文件;逐文件 sha256 与源比对
与 rocky9_eda_compat 工程的 /opt/compat 管理重叠 两边各写同一目录 本主题只补 11 个 el7 binutils 文件,不触碰 uname 与 liblcms/libmng/libtiff(那些由该工程管理)

附录:交付物清单

路径 说明
deploy_el7_binutils.py 幂等部署脚本(预演 / --apply)
templates/vcs-el7-1.0.lua.tpl modulefile 模板(单一源)
artifacts/ 从 31.18 取回的制品副本(分发真源)
backup/ 覆盖前备份与台账(README.md 为登记表)
docs/SOP.md 本文档

附:模块别名(2026-10-05,交接单 D)

  • templates/synopsys-.modulerc.lua.tpl(渲染后写入 /data/nfs/modulefiles/synopsys/.modulerc.lua): module_alias("vcs/el7", "vcs-el7/1.0") —— 让标准写法 module load vcs/el7 与原名 module load vcs-el7/1.0 并存。
  • 为何是 module_alias 而非 module_version:实测 module_version("vcs-el7/1.0","vcs/el7") 只会得到 vcs-el7/vcs/el7(别名附加到 name 所在目录);跨到顶层必须用全局别名。rc 放在 synopsys/ 家族目录,只登记本模块的别名(属主仍是本工程)。
  • deploy_el7_binutils.py 已把 modulefile 写入泛化(_install_lua)并新增 write_modulerc(); 复跑 --apply 时两者均为「内容一致,跳过」(幂等)。
  • 完整变更档案:eda_tools_ins/lmod_cross_project_fix_20261005/SOP.md 附录 C。

来源:/home/rain/Documents/eda_tools_ins/Synopsys/vcs_el7_binutils_20260929/docs/SOP.md | 最后更新:2026-10-05 17:32(由 build/sync.py 同步,请勿在站点侧修改)