You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chisel3存储单元模块寄存器值不持久化、写后读测试失败问题排查

问题原因

你遇到的问题由以下几个错误共同导致:

  • 信号名不匹配:你在接口MemristorCellBundle中定义的写控制信号名为writeBus,但模块内部错误引用了不存在的io.voltageBus,测试代码中也错误调用了c.io.write,命名不一致属于低级笔误。
  • 未明确指定位宽:中间信号write、寄存器internalValue定义时都没有指定位宽,Chisel自动推断位宽可能出现不符合预期的结果。
  • 最核心问题:测试未触发时钟沿:Chisel中Reg类型是时钟沿触发的寄存器,只有时钟发生跳变时,组合逻辑的赋值才会写入寄存器的存储单元。你的测试代码所有操作都在同一个时钟周期内完成,写入5的操作没有触发时钟沿,寄存器internalValue的值从来没有被真正更新,一直保持初始的0值。
修复方案

首先修正模块代码的命名、位宽问题,可选给寄存器添加复位初始值保证初始状态可控:

class MemristorCellBundle() extends Bundle {
    val writeBus = Input(UInt(1.W))
    val dataBus = Input(UInt(8.W))
    val cellBus = Output(UInt(8.W))
}

class MemCell() extends Module {
    val io = IO(new MemristorCellBundle())

    // 修正信号名,明确指定位宽
    val write = Wire(UInt(1.W))
    write := io.writeBus

    // 明确寄存器位宽,设置复位初始值为0
    val internalValue = RegInit(UInt(8.W), 0.U)

    when(write === 1.U) {
        internalValue := io.dataBus
        io.cellBus := io.dataBus
    } .otherwise {
        io.cellBus := internalValue
    }
}

然后修改测试代码,写入操作后步进一个时钟周期,触发寄存器更新:

class MemCellTest extends FlatSpec with ChiselScalatestTester with Matchers {
    behavior of "MemCell"
    it should "read and write" in {
        test(new MemCell()) { c =>
            c.io.dataBus.poke(5.U)
            c.io.writeBus.poke(0.U)
            c.io.cellBus.expect(0.U)
            // 写入操作
            c.io.dataBus.poke(5.U)
            c.io.writeBus.poke(1.U)
            c.io.cellBus.expect(5.U)
            // 步进一个时钟,触发寄存器把5写入存储单元
            c.clock.step(1)
            // 验证写后读
            c.io.dataBus.poke(12.U)
            c.io.writeBus.poke(0.U)
            c.io.cellBus.expect(5.U)
        }
    }
}

如果你的场景不需要复位逻辑,也可以用Reg(UInt(8.W))定义寄存器,但必须保证寄存器被使用前至少完成一次有效写入,否则初始值为未定义状态,仿真可能出现随机值。

内容的提问来源于stack exchange,提问作者Nick Felker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 07:24:07