Files
riscv-ulp-survey/rtl-mcp/README.md
T

77 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 用