新增 rtl-signal-mcp: RTL 信号追踪 MCP server(索引引擎+8工具+验收脚本)

This commit is contained in:
admin
2026-09-06 09:09:18 +00:00
parent 17a24e1f5e
commit ebad146b83
4 changed files with 879 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# rtl-signal-mcp
给 AI agent 用的 RTL 信号追踪 MCP Server。解决一个具体问题:**RTL 信号的联系跨模块分布在端口连接上,读单个文件看不出来**。本工具把整个代码库索引成"模块事实库 + 跨边界信号边",agent 查一次得一条紧凑驱动链,不用通读源码、不烧 token。
实测性能:OpenTitan 全 hw 树(31 万行 RTL)→ **971 模块 / 94,891 条跨模块边 / 10.6 秒建索引 / 310MB 内存**;单次追踪查询毫秒级、返回几百字节文本。
## 包含文件
| 文件 | 说明 |
|---|---|
| `rtl_index.py` | 核心引擎:pyslang 解析 → 模块事实库(端口/网络/assign/always/实例化)→ 跨模块边 → 驱动/负载递归查询 |
| `mcp_server.py` | MCP stdio server(纯标准库实现 JSON-RPC 2.0,无 SDK 依赖) |
| `mcp_client_demo.py` | 测试客户端(模拟 agent 完整调用序列,可当验收脚本) |
| `README.md` | 本文件 |
## 8 个工具
| 工具 | 作用 | token 成本 |
|---|---|---|
| `build_index` | 建索引(roots: 文件/目录列表) | 一次性 |
| `list_modules` | 列模块及事实计数 | 极小 |
| `module_summary` | 单模块端口/实例/连接摘要 | 小 |
| `find_signal` | 正则搜信号 → 模块 + file:line | 极小 |
| **`trace_drivers`** | **谁驱动这个信号**(跨模块递归) | **每次几百字节** |
| **`trace_loads`** | **这个信号驱动谁**(上抛+下钻) | 小 |
| `get_source` | 按行取小段源码(≤200 行) | 按需 |
| `hierarchy` | 实例化树 | 小 |
## 接入 Claude / 其他 MCP 客户端
```json
{
"mcpServers": {
"rtl-signal": {
"command": "python3",
"args": ["/path/to/rtl-mcp/mcp_server.py"],
"env": { "RTL_MCP_ROOTS": "/data/repos/e203_hbirdv2/rtl/e203:/data/repos/opentitan/hw/ip" }
}
}
}
```
`RTL_MCP_ROOTS` 冒号分隔多个目录,启动时自动预建索引;不设则由 agent 首次调用 `build_index`
依赖:`pip install pyslang`(仅此一个)。Python ≥ 3.10。
## Agent 使用模式(写进系统提示词即可)
```
调试 RTL 信号问题时按此流程:
1. find_signal 找到信号的归属模块和位置
2. trace_drivers 查驱动链(跨模块),trace_loads 查影响面
3. 只对链上关键条目用 get_source 看 file:line 附近 ±20 行
4. 绝不整文件读源码;结论引用 [kind] where :: sig <- rhs 条目
```
## 已验证范围
- E203 蜂鸟 RISC-V 核(42 文件/39 模块/1789 边/0.2s):`trace_drivers(e203_exu_alu.i_valid)` 正确给出 ALU←EXU 译码器三模块链(含 file:line)
- OpenTitan `hw/ip/aes`67 模块/1037 边)
- OpenTitan `hw/ip + top_earlgrey`841 模块/84,942 边/7s
- OpenTitan 全 hw 树(971 模块/94,891 边/10.6s/310MB
## 已知边界(诚实声明)
- 语法级分析:不做参数展开/elaboration——generate for、parameter 化的端口名按字面处理;位宽/方向冲突不检测
- always 块提取覆盖 always/always_ff/always_comb 内的阻塞与非阻塞赋值(含 if/case 嵌套与时序控制穿透),函数内赋值暂不提取
- 跨模块追踪经实例端口边递归,Max depth 默认 4(可调);未索引的第三方模块(如仅黑盒实例名)标为链尾
- SystemVerilog interface/class/sequence 未索引(面向可综合 RTL 设计)
- 同名信号在不同模块中是不同节点——查询需给 module + signal 两个参数(`find_signal` 可帮定位)
## 路线图(人用的网页版后置)
- v0.2: elaboration 级准确(走 pyslang AST 编译而不是纯语法树),generate/parameter 展开
- v0.3: 波形接入(pylibfst 读 FST,值反标到驱动链 → X 态/根因追踪);参考腾讯开源 wave-mcp
- v0.4: 网页视图(驱动链图形化 + 波形联动),给人 review 用