Rocket Chip中reg_write64写Decoupled型MMIO寄存器执行挂起问题
问题分析与解决方案
问题出在你只把Decoupled接口的bits绑定到了MMIO寄存器,但没处理Decoupled的valid和ready握手信号。当用reg_write64做64位原子写时,软件会等待硬件确认写操作完成,而你的Decoupled接口因为valid没正确置位、或者ready没拉高,导致握手无法完成,写操作一直挂起;32位写可能因为总线拆分或者默认寄存器逻辑不需要完整握手就完成了,所以能正常工作。
下面是两种可行的解决方法:
方法一:手动实现握手逻辑
自己处理MMIO写触发时的valid置位和ready响应,确保写操作能完成握手:
val wireToConnect = Wire(Decoupled(Bits(64.W))) // 存储写入的数据和触发valid的信号 val writeData = Wire(Bits(64.W)) val writeValid = RegInit(false.B) // 定义寄存器写逻辑:收到写请求时锁存数据,置位valid val writeField = RegField(64, writeData, RegField.WriteFn((data, _) => { writeData := data writeValid := true.B }) ) // 绑定Decoupled接口的信号 wireToConnect.bits := writeData wireToConnect.valid := writeValid // 当硬件侧准备好接收数据时,拉低valid完成握手 when(wireToConnect.ready && writeValid) { writeValid := false.B } // 注意:这里的ready要根据你的实际硬件模块来连接,如果硬件能立即接收就设为true.B // wireToConnect.ready := yourHardwareModule.ready wireToConnect.ready := true.B // 示例:立即接收 regmap( 0x00 -> Seq(writeField) )
方法二:用现成的Decoupled寄存器映射工具
如果你的项目依赖rocket-chip等Chisel生态库,可以直接用RegField.wDecoupled工具函数,它会自动处理握手逻辑:
import freechips.rocketchip.util._ val wireToConnect = Wire(Decoupled(Bits(64.W))) regmap( 0x00 -> Seq(RegField.wDecoupled(64, wireToConnect)) )
另外要确认:你的硬件模块侧的ready信号要正确拉高,否则即使软件触发了valid,握手还是无法完成,写操作依然会挂起。
内容的提问来源于stack exchange,提问作者CV_Ruddha
相关产品推荐
相关产品推荐

