为什么chiseltest中poked值在最后时钟周期变化导致断言失败
问题根本原因
这是ChiselTester的默认行为导致的:
测试代码块执行完毕后,框架会自动取消所有输入端口的poke驱动,将输入恢复为未驱动状态(对应值为0),并且会额外执行一次组合逻辑求值。你的示例中assert是纯组合逻辑断言,会在这次额外求值中被触发,刚好检测到io.input被重置为0,因此报错。
你看到的两次打印也对应两个阶段:第一次是调用dut.clock.step()时时钟沿触发的打印,值为你poke的3;第二次就是测试结束前自动求值阶段的打印,值为0。
解决方案(无需删除断言)
断言是RTL功能验证的有效手段,完全不需要全部移除,可根据你的场景选择对应方案:
- 方案1:将组合断言改为时序断言
如果你需要在每个时钟沿采样时校验输入值符合要求,把断言放到时钟沿触发的逻辑中即可,最后那次没有时钟沿的自动求值不会触发这类断言检查,写法参考:when(risingEdge(clock)) { assert(io.input === 3.U) } - 方案2:给断言增加有效触发条件
针对你的RISC-V解码器场景,指令只有在有效的时候才需要满足最低两位为11的要求,给断言加个有效信号的判断即可,避免复位、仿真结束等指令无效场景的误触发:when(instValid) { // instValid为你自定义的指令有效控制信号 assert(io.inst(1, 0) === "b11".U) } - 方案3:修改测试代码适配
如果你不想修改RTL代码,只需在测试代码的最后保持对应端口的poke状态即可,你的示例只需加一行代码就能解决报错:test(new AssertFail) { dut => dut.io.input.poke(3.U) dut.clock.step() dut.io.input.poke(3.U) // 新增这行,确保测试结束前的自动求值阶段输入值符合要求 }
内容的提问来源于stack exchange,提问作者Tarirah
相关产品推荐
相关产品推荐

