Skip to content

v0.2.3

Choose a tag to compare

@xxin0816 xxin0816 released this 05 Sep 11:40
· 9 commits to main since this release

wave-mcp v0.2.3

缺陷修复版本,来自真实项目实测。工具数不变(34),无 API 变更、无数据格式变更,
升级无需改动任何调用方代码。

安装

pip install --upgrade "wave-mcp[viewer]"   # 含波形查看器
pip install --upgrade wave-mcp             # 仅分析工具

主要修复

DUT 顶层信号追踪不到。 以 DUT 为根构建 netlist 时,所有直接声明在 DUT 顶层的信号
都返回 unresolved_pathsignal_drivers 一个也查不出来,尽管 netlist 里其实有这些
驱动关系。

根因是作用域解析的第三级判据读的是 FST 的 component 字段,而这个字段对波形来说
恒为空,Verilator 原生 FST 和 VCD 转出来的都一样。也就是说那段代码从来没生效过。

它一直没暴露,是因为以前都是从 testbench 顶层展开,netlist 根 key 和 FST 根 scope
同名,第一级精确匹配就把所有查询都接住了,第三级根本走不到。换成 DUT 为根就断在这里:
netlist 根是 DUT(decode),FST 根是 testbench(top_tb.U_DECODE),前两级全部落空,
正好掉进那个从来不工作的分支。现在第三级也接受 definition_name,它由 netlist 锚点推导
得出,根节点因此能解析,顶层信号恢复可追踪。

跨层次追踪只能单向。 loads() 会下钻子模块,drivers() 不会,于是同一根线在
signal_connectivity 里显示有连接,signal_drivers 却说是悬空的。现在两个方向都遍历
peer,并且按端口方向过滤:上游取同层 fan-in 加子模块的 output 口,下游取同层 loads
加子模块的 input 口。方向过滤是关键,否则一个顶层 reset 会被报成由它驱动的那些
触发器所驱动。解析结果会标明来自哪一跳。

netlist 里的源码路径打不开。 modules_in_file 恒返回 0,signal_drivers 给出的
examples/sample/counter.sv 这类路径对任何目录都解析不出来,因为路径是相对展开时的
cwd 存的,查询时却拿当前 cwd 去对。现在 netlist 构建会记录自己当时的 cwd 并优先用绝对
路径,其余相对路径在加载时统一重写一次,依次按构建根目录、netlist 目录及其祖先解析。
只做一次归一化,是因为这些路径会通过 drivers、loads、fan-in、trace 结果和声明等多条
路径到达调用方。

filelist 不认环境变量。 -F $PROJ_FE/rtl/foo.f 被当成字面量,整组文件因此静默地
以"文件缺失"退出展开。现在 token 会过一遍 os.path.expandvars;未定义的变量保持原样,
这样它仍然以文件缺失失败,而不会碰巧变成一个真实存在的路径。

时间单位写错会静默跑偏。 --cursor 1000nanoseconds 会被接受,然后落到一个任意
时刻且不报任何错,因为单位解析失败时转换器退化成输出裸数字,那和做单位换算是完全
不同的两件事。现在未知单位在 CLI 就被拒绝,同时从生成的命令批次里剔除,其余 marker
重新编号,避免一个坏条目把后面的 id 全顶错。可用单位收敛到 timeutil 里的单一列表。

IDE 内嵌浏览器里查看器全白。 页面通过 URL query string 接收后端 token,部分内嵌
浏览器会在跳转时把 query 丢掉,于是 shell 去请求一个 404 的地址,画布永远不绘制。
现在 token 随视图状态一起下发,页面会回退到它,裸 URL 也能正常工作。每个服务仍然只
在 localhost 上服务一个视图。

开视图偶发启动失败。 开一个视图要两个端口,shell 一个、surver 一个,两个都是先
bind 一个 socket 读出端口号、关掉、稍后再 bind 一次。中间这段端口无主,宿主机上任何
进程都可能抢走,第二次 bind 就失败。它只在有负载时复现,比如全量回归快速连开多个
视图,表现为随机的 "surver failed to start"。

两个调用方的修法不同,因为其中一个没法持有自己挑的端口。shell server 现在直接接收
一个已在监听的 socket,挑端口和 bind 变成同一个操作,窗口彻底消失。surver 是外部
二进制、只收一个端口号,没法继承 socket,所以改成子进程起不来就弃用这个端口、换一个
重试;只有 bind 失败才重试,波形缺失、二进制不可执行这类确定性错误仍然第一次就报出来。

测试

新增 tests/unit/test_dut_root.py,用 pylibfst 现场合成波形来钉住上面第一个问题,
不需要仿真器,也不会被仓库里过期的波形文件掩盖。它不只断言结果,还断言"这个 bug
可达"的前提条件,所以后续改动没法悄悄把它变成对叶名匹配的测试。把修复回退掉,8 个
断言里有 5 个会失败。

兼容性

无破坏性变更。alloc_port() 保持原签名,新增的可选 exclude 参数用于重试时跳过已知
不可用的端口。全量回归 9/9 通过。

完整能力

34 个 MCP 工具 / 8 大类:层次探索、信号查询、值查询、驱动分析、值/X 态追踪、波形查看
器、pass/fail 对比、视图生命周期。输入格式 FSDB / VCD / FST,已在 Xcelium 上适配。
不依赖任何商用 EDA 工具。