# NutShellGPUbackend **Repository Path**: gpuap/NutShellGPUbackend ## Basic Information - **Project Name**: NutShellGPUbackend - **Description**: NutShellGPUbackend: backend for NutShellGPU - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2026-09-26 - **Last Updated**: 2026-10-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NutShellGPUbackend —— OpenROAD RTL→GDS 基线流程 **Version**:1.0 **Authors**:Di Zhao (zhaodi@ucas.ac.cn), Trae CN **顾问**:王志昂,复旦大学助理教授,OpenROAD-Research(GPU版本OpenROAD)主持人 **成果预览**:学生最小规格(warps=2 / lanes=4 / 栈深 8,24,275 单元)跑完全流程后, 可得到**架构分区标注版图**——三个架构模块在硅片上互不重叠,与课件架构图一一对应。 标注层配色:999/1 黄绿 = **nsm 核**(左侧大块,12,514 实例);999/2 粉红 = **nsm/scoreboard**(中间竖窄条,402 实例);999/3 蓝 = **nsm/simt_stack**(右侧大块, 11,359 实例);999/4 青 = 顶层胶合逻辑 top_glue 与走线走廊。nsm 是五级流水线主体, scoreboard 是"为每条指令记档"的小状态机(故而面积小),simt_stack 是 4 位宽、8 项 深的分支分歧栈。跑法与验收见 §0.2: ![NutShellGPU 架构分区标注版图](docs/nutshellgpu_partitioned_layout.png) 把裁剪后的 GPU 后端核 `NutShellGPUbackend`(2 warp / 16 寄存器 / 64×32b IMEM)用 **sky130A + sky130_fd_sc_hd(tt_025C_1v80 单角)** 从 RTL 一路跑到 GDSII + DRC + LVS 的可复现基线流程,运行在每人 **2 核 / 10GB 内存** 的 H20 服务器 Docker 容器内。 本 README 同时给出: - 第 5 章:**全流程每个步骤的详细 profiling 方法**(计时、内存、CPU 利用率、火焰图); - 第 6 章:**利用 H20 GPU + AI coding 改进 OpenROAD、提升全流程速度的具体建议**。 --- ## 0. Quick Start(4 步,5 分钟上手) ```bash # ① clone 仓库(自包含,跑流程期间零联网) git clone https://gitee.com/gpuap/NutShellGPUbackend.git cd NutShellGPUbackend # ② 下载镜像 tar 并导入(1.42GB,仅做一次) # 百度网盘:https://pan.baidu.com/s/1q8plm8L2pU55w3qpDqdkUg?pwd=zc3k(提取码 zc3k) docker load -i openlane_2024.09.22.tar # ③ 冒烟(ORFS gcd 小设计,全绿约 16 分钟,验证环境无问题) SMOKE=1 bash flow/docker_run.sh # ④ 正式设计全流程(NutShellGPUbackend,产出最终交付物) bash flow/docker_run.sh ``` 看到 `baseline/baseline_result.csv` 就成功了,交这份文件: ``` total_cells,chip_area_um2,...,WNS,TNS,DRV_count,DRC_result,LVS_result 237,667807.67,...,-5.44,-211.86,0,Pass,Fail ← 冒烟(gcd)参考值(实测) ``` - **DRC=Pass 即验收通过**;LVS=Fail 是已知工具限制(不影响交付,见 5.3) - 中途失败?`tail -40 baseline/logs/<阶段>.log` 看最后 40 行,改完直接重跑 `bash flow/docker_run.sh`(自动断点续跑) - 只重跑某阶段:`ONLY=synth bash flow/docker_run.sh`(标签见 baseline/stage_time_summary.txt) - 服务器上没有该镜像?让管理员预装,或按第 2 章"离线服务器"小节导入 --- ## 0.1 学生须知(clone 即全量,运行零联网) **本仓库自包含**:RTL、OpenROAD/Yosys/Magic/Netgen/sky130 全部源码、 ORFS 参考、流程脚本,一次 `git clone` 全部拿到,**跑代码期间无需任何网络**。 网络只在**一次性准备**阶段用到(且都可以绕过): | 一次性事项 | 需要网络? | 说明 | |---|---|---| | `git clone` 本仓库 | 需要(或从课程网盘/U盘拷贝仓库目录) | 包含全部代码与源码 | | 准备 Docker 镜像 | **不需要** | 镜像 tar 包由课程统一分发,或按第 2 章"离线服务器"小节导入 | 之后在服务器上全程离线: ```bash # 第 1 步:确认镜像存在(管理员预装则跳过导入) docker images | grep openlane # 没有的话:bash flow/docker_image_offline.sh load openlane_2024.09.22.tar.gz # 第 2 步:冒烟(几分钟,验证环境) SMOKE=1 bash flow/docker_run.sh # 第 3 步:正式全流程 bash flow/docker_run.sh # 结果:baseline/baseline_result.csv + stage_time_summary.txt ``` > 为什么运行不需要联网:EDA 工具(yosys/openroad/magic/netgen)与 sky130 PDK > 都在 Docker **镜像内**;RTL/脚本通过 volume 挂载进容器;全流程没有任何 > curl/wget/apt/pip/git 网络调用。 --- ## 0.2 学生版全流程总结(三条口径,2 核 / 9GB 实测) 顶部预览图即学生最小规格的实测产物。三条考核口径: | 口径 | 命令 | 实测耗时 | 产出 / 验收 | |---|---|---|---| | 入门冒烟 | `SMOKE=1 bash flow/docker_run.sh` | ≈14 分钟 | DRC=Pass 即达标 | | **期末大作业**(学生最小规格,默认冻结基线) | 见下方命令 | **≈2h10m** | 16 列 CSV + 架构标注 GDS,DRC 全干净(0 违例) | | 拔高选做(架构硬分区版,即顶部预览图) | 同命令追加 `FENCE=1 DRT_END_ITER=10` | ≈3h50m | 三模块互斥分区 GDS | 期末大作业运行命令(在服务器仓库根目录执行): ```bash # 学生最小规格:4 lane / 栈深 8,与期末考试 4-lane 手算题同构 # NUM_WARPS=2 / RF_REGS=8 / IMEM=64 已是 env.config 冻结值,无需再传 CORE_UTIL=30 \ RTL_NUM_LANES=4 \ RTL_SIMT_STACK_DEPTH=8 \ KEEP_HIER=1 \ SKIP_VALIDATE=1 \ BASELINE_DIR=/work/baseline_student \ bash flow/docker_run.sh # 拔高选做:在上面变量基础上追加两项(分区版实测留 ~1.3k 个布线违例, # 属教学演示可接受范围;不追加 DRT_END_ITER 则布线跑满收敛) # FENCE=1 DRT_END_ITER=10 ``` > **注意**:`BASELINE_DIR` 每换一组 RTL 参数必须换一个新目录(断点续跑只认 > 顶层模块名,复用旧目录会错误沿用旧网表)。验收三件套: > ① KLayout 打开 `GDS/_annotated.gds` 能指出三个分区; > ② `GDS/_modules.txt` 实例数与综合报告一致(12,514 / 11,359 / 402); > ③ 综合/布局日志无 ERROR,利用率 30% 量级。 --- ## 1. 目录结构 ``` NutShellGPUbackend/ ├── flow/ # 本流程全部代码 │ ├── env.config # 唯一允许手改的配置(镜像/路径/裁剪/冻结参数) │ ├── config.tcl # OpenROAD 公共配置:PDK 路径、track、层 RC、公共过程 │ ├── constraints.sdc # 统一时序约束(50MHz、IO delay、driving cell/load) │ ├── pdn_sky130hd.tcl # 电源网络(逐字对照 ORFS sky130hd/pdn.tcl) │ ├── 01_synth.tcl # Yosys 逻辑综合 │ ├── 02_floorplan.tcl # 布局规划 + tapcell + IO 引脚 │ ├── 03_placement.tcl # PDN + 全局布局 + 详细布局 │ ├── 04_cts.tcl # TritonCTS 时钟树 │ ├── 05_global_route.tcl # FastRoute 全局布线 + 拥塞报告 │ ├── 06_detail_route.tcl # TritonRoute 详细布线 + filler │ ├── 07_rcx_parasitics.tcl # OpenRCX 寄生提取 → SPEF │ ├── 08_sta.tcl # OpenSTA post-route 时序分析(WNS/TNS 落指标) │ ├── 09_write_gds.tcl # 导出最终 DEF/网表;GDS 由 KLayout def2stream 合并 │ ├── 10_drc_lvs.tcl # Magic DRC + 版图网表提取(KLayout LVS 在 run_all 调) │ ├── run_all.sh # 全流程入口(计时/RSS/断点续跑/裁剪闸门) │ ├── collect_metrics.sh # 生成 16 列 CSV + 阶段耗时排序表 │ ├── docker_run.sh # 宿主机一键入口(限 2 核 9GB) │ ├── docker_image_offline.sh # 离线镜像搬运(save/load,服务器不能上网时用) │ ├── Dockerfile # 固定工具链镜像 │ ├── dont_use.list # abc 禁用单元(慢的 lpflow 系列 + probe 单元) │ ├── lvs_setup.tcl # netgen LVS 设置(已弃用,保留作参考;现用 KLayout LVS) │ ├── drc/ │ │ └── sky130A.lydrc # KLayout DRC deck(PDK 逐字副本,foundry 原生规则) │ ├── klayout/ │ │ └── sky130A.lyt # KLayout LEF/DEF 工艺描述(s09 自动注入 LEF 路径) │ ├── lvs/ │ │ ├── sky130hd.lylvs # ORFS KLayout LVS deck │ │ ├── sky130hd.cdl # ORFS sky130hd 标准单元 CDL 定义 │ │ └── sky130.lylvs # PDK KLayout LVS deck(参考用) │ ├── util/ │ │ ├── def2stream.py # ORFS 官方 DEF+单元GDS → 最终 GDS(含 via 切层) │ │ ├── generate_klayout_tech.py # 由 .lyt 模板生成实际 KLayout 工艺文件 │ │ ├── dump_module_bbox.tcl # ODB dbModule 树 → 模块足迹 mmod(标注用) │ │ ├── annotate_modules.py # KLayout 998/999 层叠加模块分区标注 → *_annotated.gds │ │ └── apply_module_fences.tcl # FENCE=1 时三模块硬分区(dbRegion+dbGroup+dbPowerDomain) │ └── lib/ │ └── metrics.tcl # 指标写入公共过程 ├── NutShellGPU/ # 已裁剪 RTL(NutShellGPU_hw/rtl)+ 模拟器 + 规范文档 ├── openroad/ # OpenROAD 完整源码(参考/研究用,运行不依赖) ├── openroad-flow-scripts/ # ORFS 完整源码(参考用) ├── reference/orfs/ # ORFS 课程参考子集:platforms/sky130hd + scripts + gcd ├── yosys/ magic/ netgen/ skywater130/ # 小工具链源码快照(可选阅读) ├── Proposal.md # 方案文档 └── baseline/ # 运行后生成(产物、日志、CSV) ``` > 仓库说明:学生 `git clone` 本仓库即可运行——RTL、完整工具链源码 > (`openroad/`、`openroad-flow-scripts/`、`yosys/`、`magic/`、`netgen/`、 > `skywater130/`)、`reference/orfs/` 参考子集、流程脚本全部包含。 > 注:ORFS 中与本课程无关的 `sky130ram` 平台里一个 100MB SRAM LEF 文件 > 超出 Gitee 单文件限制,已移除(不影响 sky130hd 流程)。 ## 2. 环境与镜像 | 项 | 值 | |---|---| | 服务器 | H20 GPU 服务器,每账号配额 **2 vCPU / 10GB RAM** | | 宿主机依赖 | 仅需 Docker(无需本机装 yosys/openroad) | | 镜像 | `efabless/openlane:2024.09.22`(**课程烘焙版,约 8.2GB**:yosys/openroad/magic/netgen/klayout + 预装 `/opt/pdk` 的 sky130A PDK + awk 补丁) | | 工艺 | sky130A / sky130_fd_sc_hd / `tt_025C_1v80` 单角 | | 资源限制 | `docker run --cpus 2 --memory 9g`(留 1GB 给系统) | ### 离线服务器:镜像导入(服务器不能上网时) 课程已把镜像 tar 上传到百度网盘,H20 服务器无法访问 Docker Hub 时按以下步骤离线搬运: **下载镜像 tar(1.42 GB)**: > 百度网盘链接:https://pan.baidu.com/s/1q8plm8L2pU55w3qpDqdkUg?pwd=zc3k > 提取码:`zc3k`(有效期至 2027-09-27) ```bash # 0) 从网盘下载 openlane_2024.09.22.tar 后,拷到 H20 服务器 # 1) 导入镜像 docker load -i openlane_2024.09.22.tar # 2) 验证镜像存在(应显示 efabless/openlane:2024.09.22) docker images efabless/openlane:2024.09.22 # 3) 之后正常运行 bash flow/docker_run.sh ``` 若管理员已在服务器预装了其他 tag 的 openlane 镜像(`docker images` 查看), 直接把 `flow/env.config` 的 `DOCKER_IMAGE` 改成该 tag 即可,无需导入。 > **M0 必做核实**(导入课程镜像后,进容器执行): > > ```bash > docker run --rm efabless/openlane:2024.09.22 bash -c ' > ls /opt/pdk/sky130A/libs.ref/sky130_fd_sc_hd/techlef/sky130_fd_sc_hd__nom.tlef > ls /opt/pdk/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds > openroad -version; yosys -V; magic -version; klayout -version > netgen -batch eval quit; awk "BEGIN{print \"AWK_OK\"}"' > ``` > > 全部存在且最后打印 `AWK_OK` 即为课程烘焙镜像。PDK 路径已固定为 > `/opt/pdk`(`flow/env.config`),无需再改。镜像 digest 回填到 > `DOCKER_DIGEST`(`docker inspect --format '{{index .RepoDigests 0}}' `)。 ## 3. 一键运行 在 H20 服务器上,**仓库根目录**执行: ```bash # 第 0 步:冒烟(强烈建议先跑,约几分钟,验证工具链/PDK/路径) SMOKE=1 bash flow/docker_run.sh # 第 1 步:正式设计全流程 bash flow/docker_run.sh ``` 容器跑完后产物全部在宿主机 `baseline/` 下(volume 挂载)。 ### 常用运行模式(run_all.sh,容器内) | 命令 | 作用 | |---|---| | `bash flow/docker_run.sh` | 默认从第一个缺失产物的阶段**断点续跑**(RESUME=1) | | `RESUME=0 bash flow/docker_run.sh` | 忽略已有产物,从头重跑 | | `SMOKE=1 bash flow/docker_run.sh` | 用 ORFS 自带 gcd 小设计验证流程 | | `ONLY=detail_route bash flow/docker_run.sh` | 只重跑某个阶段(计时标签名) | ### 规模裁剪闸门 综合后若实例数 **> 100000**(`SYNTH_CELL_GATE`),流程自动中止——10GB 内存 跑 P&R 大概率 OOM。此时把 `env.config` 的 `RTL_RF_REGS=8`、`RTL_IMEM_SIZE=32` 调小后重跑即可,**不需要改任何 RTL 文件**(Yosys `chparam` 在综合时覆盖)。 ### 可选:使用自带 Dockerfile 的本地镜像 默认直接使用云端 `efabless/openlane` 镜像。需要 `/usr/bin/time` 等额外工具时可本地构建, 然后把 `env.config` 的 `DOCKER_IMAGE` 改成本地 tag: ```bash docker build -f flow/Dockerfile -t nutshellgpu-flow:local . # env.config: DOCKER_IMAGE=nutshellgpu-flow:local ``` ### Windows 检出注意 `.sh/.tcl/config` 必须是 **LF 行尾**(仓库根 `.gitattributes` 已强制)。 若在服务器上出现 `bash\r: bad interpreter`,执行: ```bash sed -i 's/\r$//' flow/*.sh flow/*.tcl flow/lib/*.tcl flow/env.config ``` ## 4. 冻结的基线参数 基线一经跑通**不得修改**以下参数,所有后续加速优化都与本基线做 A/B 对比: | 参数 | 值 | 说明 | |---|---|---| | 时钟 | 20ns(50MHz) | GPU 核 5 级流水 1GHz 不可达,基线取 50MHz;仍违例再降到 40ns 并在报告说明 | | uncertainty / IO delay | 0.2ns / 2.0ns | | | 核心利用率 / 宽高比 / margin | 0.30 / 1.0 / 4.0um | | | 布局 site / 密度 | unithd / 0.60 | 对照 ORFS sky130hd | | 布线层 | 信号 met1–met5,时钟 met3–met5 | 资源折减 0.20 | | tap / filler / CTS buffer | tapvpwrvgnd_1 / fill_8..1 / clkbuf_1..16 | 对照 ORFS | | 线程数 | 2 | 与账号配额一致,避免超配抖动 | ## 5. 全流程详细 Profiling 方案 > 目标:回答两个问题——**时间花在哪、内存花在哪**;这是第 6 章所有加速建议的前提, > 也是课程"每步详细 profiling"要求的直接证据。 ### 5.1 流程已内置的 profiling(零额外操作) `run_all.sh` 的 `run_timed` 对每个阶段采样: - **wall-clock 耗时**:`date +%s.%N` 前后差值,写入 `baseline/metrics/time_.kv`; - **峰值物理内存(VmHWM)**:后台运行阶段进程,每 5 秒读一次 `/proc//status` 的 `VmHWM`(真实驻留峰值,不是虚拟内存); - 每阶段完整 stdout/stderr:`baseline/logs/.log`。 跑完 `collect_metrics.sh` 自动生成: 1. **`baseline/baseline_result.csv`**——课程规定的 16 列结果(见 5.5); 2. **`baseline/stage_time_summary.txt`**——各阶段耗时降序、占总时间百分比、 峰值 RSS(MB),即一张"瓶颈排行榜",例如: ``` # stage, elapsed_s, pct_of_total, peak_rss_MB (sorted by elapsed desc) detail_route 512.30 s 41.2% 6200.4 MB placement 233.10 s 18.7% 3100.2 MB global_route 180.40 s 14.5% 2800.7 MB ... ``` 阶段计时标签(CSV 中 `time_gds_write` 为后三项之和): `synth, floorplan, placement, cts, global_route, detail_route, rcx, sta, write_def, lyt_tech, gds_stream`; s10 另计 `10_drc`(magic 提取)、`10_klayout_drc`(foundry deck DRC)、`10_lvs`(netgen)。 ### 5.2 进程级:perf stat / time(IPC、缓存、上下文切换) OpenLANE 镜像默认不带 perf,**在 H20 宿主机上直接 attach 容器进程**最省事: ```bash # 1) 找到容器里 openroad 的宿主 PID docker inspect -f '{{.State.Pid}}' # 容器 init pgrep -P $(docker inspect -f '{{.State.Pid}}' ) # 找 openroad/yosys PID # 2) 硬件计数器(IPC 低 => 内存/分支受限;cs 多 => 2 核超配或 IO 等待) perf stat -e task-clock,context-switches,cpu-migrations,page-faults,\ cycles,instructions,cache-references,cache-misses,branches,branch-misses \ -p -- sleep 直到阶段结束 # 备选:整体一次性量某阶段(镜像内) /usr/bin/time -v openroad -exit -no_init flow/06_detail_route.tcl # 关注:Maximum resident set size、Percent of CPU this job got、 # Minor/Major page faults、Voluntary/Involuntary context switches ``` 判读: - `instructions/cycles`(IPC)显著 < 1 且 `cache-misses` 高 → 内存带宽/延迟受限, 这类阶段最适合 GPU/数据并行(见 6.3); - `Percent of CPU` ≈ 100%×2 才说明 2 线程吃满;长期只 ~100% → 串行段占主导, 加线程没用,要做算法并行; - major page fault 多 / RSS 贴近 9GB → 内存压力导致换页,先降规模或减并发数据结构。 ### 5.3 函数级:perf 火焰图(定位"具体哪个函数慢") ```bash # 宿主机(内核符号需与宿主匹配;容器内进程共享宿主内核) perf record -F 99 -g -p -- sleep 60 # 采 60s 热点阶段 perf script > out.perf git clone --depth 1 https://github.com/brendangregg/FlameGraph /tmp/FlameGraph /tmp/FlameGraph/stackcollapse-perf.pl out.perf | /tmp/FlameGraph/flamegraph.pl > or.svg ``` 若要看到 OpenROAD C++ 函数名/行号,需要自编译带符号的版本(见 5.4)。 火焰图中应重点预期出现的热点名字(按阶段): | 阶段 | 预期热点函数/模块 | |---|---| | 03 placement | `GlobalPlacer` 解析力场迭代(Nesterov/`po*` 系列)、密度罚、`legalize` | | 04 cts | `TritonCTS` 建树、buffer insertion(通常占比很小) | | 05 global_route | `FastRoute` maze routing / pattern routing、拥塞迭代 `grt::*` | | 06 detail_route | `TritonRoute` maze search、rip-up&reroute、DRC 修复(全流程第一热点) | | 07 rcx | OpenRCX 几何扫描/模式匹配、耦合电容查表 | | 08 sta | OpenSTA 图遍历(一般很快,非瓶颈) | ### 5.4 更重的 profiling 手段(按需) - **gprof**:自编译 OpenROAD,`cmake -DCMAKE_CXX_FLAGS="-pg" -DCMAKE_EXE_LINKER_FLAGS="-pg"`, 跑完单阶段后 `gprof openroad gmon.out`;注意 `-pg` 会改变多线程行为,只用于定位。 - **valgrind massif / heaptrack**:堆内存画像,回答 RSS 被哪些容器吃掉 (如 TritonRoute 的 grid/node 数组): `heaptrack openroad -exit -no_init flow/06_detail_route.tcl && heaptrack_print heaptrack.*.gz | less`。 - **阶段内计时点**:OpenROAD Tcl 可在怀疑的命令前后插 `puts [clock milliseconds]` (基线脚本不动,复制一份 profile 版脚本做),区分例如 `global_placement` 内部 粗布局 vs 合法化的时间。 - **线程利用率**:`perf stat -e sched:sched_switch` 或宿主 `top -H -p `, 确认 `set_thread_count 2` 后两个 worker 真正并行;OpenROAD 不少前置处理是单线程。 - **对比基线**:任何优化前后都重跑同一阶段(`ONLY=`),用 `stage_time_summary.txt` 的同一行做差,避免被其他阶段噪声干扰。 ### 5.5 各阶段计算特征与 profiling 要点(逐阶段) | # | 阶段 | 输入→输出 | 计算特征 | 主要看什么 | |---|---|---|---|---| | 01 | synth | RTL→门级网表/spice | Yosys+ABC:AIG 优化、DAG 遍历,**单线程** | stat 实例数(闸门)、ABC 映射耗时;CPU 型,IPC 中高 | | 02 | floorplan | synth.v→2_floorplan.odb | die/core 计算、tapcell、pin 放置,**很快** | 基本不占时间,作正确性检查点(面积=chip_area_um2) | | 03 | placement | 2→3_place.odb | Nesterov 解析力场 + 合法化,**CPU/内存双高**、部分并行 | wall time、RSS、力场迭代次数、cache-miss、并行度 | | 04 | cts | 3→4_cts.odb | 树构建+buffer 插入,规模相关、较快 | skew 报告;一般不是瓶颈,不值得 GPU 化 | | 05 | global_route | 4→5_grt.odb/.guide | 多轮拥塞迭代 + maze wavefront,**网格图搜索、可并行度高** | 各 congestion 轮次耗时、RSS、拥塞报告 overflow | | 06 | detail_route | 5→6_route.odb | TritonRoute:迷宫搜索 + rip-up/reroute + DRC 修复,**内存/带宽最密集、第一热点** | wall、RSS(警惕 OOM)、violations、IPC、火焰图 | | 07 | rcx | 6→SPEF | 几何扫描 + 规则模式匹配,数据并行潜力 | 规则匹配热点、RSS | | 08 | sta | 6+SPEF→sta.rpt | 时序图传播,很快 | WNS/TNS;只做正确性,不优化 | | 09 | gds | 6→final.def→GDS | KLayout `def2stream`:LEF/DEF 金属与 viarule 切孔渲染 + 标准单元 GDS 合并(ORFS 官方路径),IO 型、很快 | 三段计时 write_def / lyt_tech / gds_stream;"LEF Cell ... empty" 说明单元 GDS 缺失 | | 10 | drc/lvs | GDS→drc*.rpt/lvs.rpt | magic 全片 DRC + 版图 SPICE 提取(较慢)、**KLayout sky130A foundry deck DRC(权威)**、netgen 图同构 | `10_klayout_drc` 耗时/内存、`drc_klayout.lyrdb` items=0、LVS `CORRECT` | > 预期结论(以实测为准):**detail_route > placement ≈ global_route** 吃掉绝大部分 > 时间与内存;这三处也正是第 6 章 GPU/并行加速的主战场。 ### 5.6 CSV 16 列字段定义(baseline_result.csv) | 列 | 含义 / 来源 | |---|---| | `total_cells` | 综合后实例数(01 日志 `Number of cells:`) | | `chip_area_um2` | 核心面积 μm²(02 阶段,DBU÷1e6) | | `time_synth` … `time_gds_write` | 9 个阶段 wall-clock 秒数(time_*.kv) | | `WNS` / `TNS` | post-route setup 最差负裕量 / 总负裕量(sta_setup.rpt / 08 日志) | | `DRV_count` | 详细布线残留违规数(TritonRoute `Number of violations`) | | `DRC_result` / `LVS_result` | KLayout foundry deck(`drc_klayout.lyrdb`)items=0 → Pass;KLayout LVS `Congratulations` → Pass,`don't match` → Fail。**已知限制**:OpenROAD `write_cdl` 对含转义方括号的网名丢 cell name,导致 tap/filler 侧数量不匹配;逻辑单元(243 vs 243)已对齐,不影响 DRC 和 GDS 交付 | ## 6. 利用 H20 GPU + AI Coding 加速 OpenROAD 的建议 > 重要前提:**OpenROAD 官方主线是 CPU 程序**,没有可用的生产级 GPU 后端。 > GPU 化属于**研究性扩展**,必须在"结果等价"护栏下进行: > **DRC/LVS 仍 Pass、WNS/TNS 不退化、DRV 不增加**,加速才算数。 > 一切优化以第 5 章的 profiling 数据驱动,禁止凭感觉改。 ### 6.1 为什么 H20 适合/不适合这个任务 H20(Hopper 架构、中国特供版)的特点决定了适用边界: - **96GB HBM3、约 4TB/s 显存带宽、显存极大** → 适合放得下整张布线网格/力场网格、 吃带宽的批量数据处理(布局力场、maze wavefront、几何扫描); - **FP64 算力弱(约 1 TFLOPS 级),BF16/FP8/INT 强** → 不要指望双精度矩阵求解; EDA 算法主要是整型/图遍历,反而契合; - **H2D/PCIe 搬运有固定开销** → 小设计(本作业 <10 万单元)单次 kernel 可能 得不偿失,必须批量提交、kernel 融合、减少往返; - 每账号 **2 核 CPU** 很容易成为喂数据瓶颈 → GPU 路径要尽量减少 CPU 端 序列化/解析(LEF/DEF/网格构建仍在 CPU,是隐藏瓶颈)。 ### 6.2 热点优先级(按 5.5 的实测排序决定动手顺序) **优先级 1:全局布局(03)——最成熟的先例:DREAMPlace** - 学术/工业界已有 GPU 解析布局器 **DREAMPlace**(PyTorch/CUDA,把 wirelength/density 力场算子化),在百万单元级有数量级加速,证明路线可行; - 改造方式(由易到难): 1. 先在 OpenROAD 外做 A/B:用 DREAMPlace 读同一 floorplan 网表产出 `.def`/`.odb` placement,再喂回本流程 04 之后——**不碰 OpenROAD 源码即可验证收益**; 2. 若收益确认,再考虑把 `grt`/`gpl` 的力程 kernel 用 CUDA 重写并通过 odb C++ API 回写坐标; - 等价性护栏:`check_placement` 无 overlap、最终 WNS/DRC/LVS 与基线一致。 **优先级 2:全局布线 maze routing(05)——网格 wavefront 天然数据并行** - FastRoute 的 maze expansion 本质是网格上的**多源波前传播(类 BFS/最短路径)**, 学术上 FastRoute GPU 化先例(GPU 并行 maze、批量 net 同批处理); - 可做的增量改造: - 两-pin net 的 pattern routing 批量并行( embarrassingly parallel ,可先 OpenMP/TBB 验证多核收益,再 CUDA); - 拥塞代价更新改为结构化数组(SoA)放 HBM,wavefront 用 CUDA block 分块; - 保留迭代收敛判据与溢出报告,逐轮对比 overflow 曲线。 **优先级 3:详细布线(06)——收益最大但最难,先做 CPU 并行再谈 GPU** - TritonRoute 是第一热点,其 maze search 是逐 net/逐区域的不规则图搜索, **控制流发散严重**(GPU SIMT 最怕),且内存占用逼近 9GB; - 现实路线: 1. 先吃 CPU 侧并行:确认并调大 worker、并行独立 net 的搜索、减少全局锁; 2. 再把规则、批量、区域独立的子问题(如 access pattern、pattern routing、 批量 DRC 规则检查)offload 到 GPU;不规则主干仍留 CPU; 3. 内存:把节点结构紧凑化(SoA + 32-bit 索引),既省 RSS 又利于 GPU 搬运。 - 护栏最严:逐 net 比对 routing 结果与 `output_drc` 报告,必须零差异/零新增违规。 **优先级 4:OpenRCX 寄生提取(07)——数据并行甜点** - 几何扫描/模式匹配是规则的批量几何运算,适合 GPU(空间分块 + 并行查表); - 但只有当 profiling 显示它占比可观才值得(通常不是第一瓶颈)。 **明确不建议 GPU 化**:01 Yosys/ABC(单线程 DAG/逻辑优化,控制流不规则且有成熟 CPU 实现)、04 CTS、08 STA、09 GDS 序列化——占比小或无并行价值,违背 Amdahl 定律。 ### 6.3 不写 CUDA 也能拿到的"快胜"收益(先做,风险最低) 1. **编译优化**:用 `-O3 -march=x86-64-v3 -flto` 自编译 OpenROAD(基线镜像用通用 编译参数),对比 `stage_time_summary.txt`,热点常能拿到 10–30%; 2. **内存分配器**:换 jemalloc/mimalloc(`LD_PRELOAD`),对大量小对象的 TritonRoute/Yosys 常有明显收益; 3. **线程与超配**:固定 `--cpus 2`、`set_thread_count 2`,避免与他人争用; 火焰图确认串行段后,把并行预算集中给 detail route; 4. **阶段内算法参数的等价裁剪**(属于优化实验,**不得改冻结基线**,另开 `optimized/` 目录跑):如减少 global route 无效拥塞迭代轮数上限(基线固定 30)、 调整 detail route verbose/迭代策略,用 A/B CSV 证明质量不退化; 5. **IO/内存**:WORK_DIR 指到本地 NVMe 临时盘(`env.config` 注释已说明), 避免网络盘上 GDS/DEF 读写抖动。 ### 6.4 推荐的 AI coding(Trae)优化闭环 把 AI 用在"读代码、生成改造、构造回归"上,而不是让它盲改算法: 1. **Profile**:按第 5 章拿到火焰图 + `stage_time_summary.txt`,锁定第一热点 (预期 06/03/05); 2. **让 AI 定位代码**:把火焰图函数名给 AI,让它在 `openroad/src/{grt,gpl,drt,rcx}` 中定位调用链、数据结构、并行现状 (哪些已有 worker pool、哪些是串行循环),输出"热点函数→源文件:行号"清单; 3. **让 AI 出最小改造方案**:例如"把这个两-pin net 的 pattern routing 循环改成 与现有 taskSystem 一致的并行 for,保持结果确定性",先 OpenMP 级改造拿 CPU 收益, 再评估 CUDA; 4. **让 AI 写 A/B 与回归**:自动生成 `ONLY=` 的前后跑批脚本、diff `baseline_result.csv` 的 WNS/DRV/DRC/LVS,并比对 odb/def 关键结果; 5. **小步提交、逐项验等价**:每次改动只覆盖一个热点 kernel,护栏四条 (DRC Pass、LVS Pass、WNS 不退化、DRV 不增加)任一不过立即回退; 6. **GPU 分支隔离**:CUDA 改造放在独立编译选项/分支,基线流程永远保持 纯 CPU 可跑,作为正确性黄金参照。 提示词示例(可直接用): > 这是 perf 火焰图显示的热点 `dr::... maze search`(附折叠栈)。请在 OpenROAD > 源码中定位它,说明数据依赖与可并行边界,给出一个不改变布线结果、使用现有 > 并行基础设施的最小 patch,并列出验证等价性需要 diff 的产物和命令。 ### 6.5 提速度量与验收 - 主表:优化前后 `stage_time_summary.txt` 并列对照(秒、占比、RSS MB), 附总 flow wall time 与相对基线加速比; - 质量回归(每次必做): | 指标 | 要求 | |---|---| | DRC_result / LVS_result | 均 Pass(与基线相同) | | WNS / TNS | 不劣于基线(变差需报告并解释) | | DRV_count | 不增加 | | chip_area / total_cells | 一致(布局布线优化不应改网表规模) | - 至少在 **gcd 冒烟 + NutShellGPUbackend 正式设计**两套数据上验证,避免只对单例有效。 ## 7. 里程碑 | 里程碑 | 内容 | 通过标准 | |---|---|---| | M0 | 服务器拉镜像、核实 PDK_ROOT、回填 digest、跑通综合记录实例数 | env.config 路径全部存在;实例数回填 M0_TOTAL_CELLS | | M1 | `SMOKE=1` gcd 全流程 | DRC/LVS 双 Pass,16 列 CSV 生成 | | M2 | 正式设计全流程(必要时按闸门降裁剪规模) | 16 列 CSV 完整、DRC/LVS Pass、时序有结论 | | M3 | 瓶颈分析 + 加速建议/实验 | stage_time_summary 排序、火焰图、第 6 章 A/B 数据 | ## 8. 常见失败速查 | 现象 | 原因 / 处理 | |---|---| | `找不到工艺文件 ...` | PDK_ROOT 不对,按第 2 章 M0 步骤核实并改 env.config | | 综合后流程中止并提示超闸门 | 实例数 >10 万,降 `RTL_RF_REGS/RTL_IMEM_SIZE` 后重跑 | | 06 阶段被 kill / RSS 贴近 9GB | 内存不足:先确认裁剪规模;再降并发、WORK_DIR 换本地盘 | | 09 阶段报 `LEF Cell ... has no matching GDS` | KLayout 合并时找不到标准单元 GDS;确认 `env.config` 的 PDK 路径下 `libs.ref/$SCL/gds/$SCL.gds` 存在(课程烘焙镜像必有) | | 10 阶段 KLayout LVS Fail | `write_cdl` 对含 `\[` 转义方括号的网名丢 cell name(OpenROAD bug),导致 tap/filler 侧数量不匹配。逻辑单元(243 vs 243)已对齐。DRC=Pass 是权威验收 | | `bad interpreter: /usr/bin/env bash\r` | CRLF 问题,执行第 3 章的 sed 去回车 | | 改坏了想重来 | `RESUME=0 bash flow/docker_run.sh`,或删除 `baseline/` 整目录 |