# 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 用