【问题标题】:Chisel persist value in module until new write凿子将值保留在模块中,直到新写入
【发布时间】:2022-01-08 14:33:15
【问题描述】:

我创建了一个基本模块,用于表示 Chisel3 中的一个内存单元:

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 MemCellBundle())

    val write = Wire(UInt())
    write := io.voltageBus

    val internalValue = Reg(UInt())
    // More than 50% of total voltage in (255).
    when(write === 1.U) {
        internalValue := io.dataBus
        io.cellBus := io.dataBus
    } .otherwise {
        io.cellBus := internalValue
    }
}

我想要的是它在write 总线为逻辑低电平时输出internalValue,并用逻辑高电平更改此值。我对 Chisel 的理解是寄存器可以在时钟周期之间持久化这个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.write.poke(0.U)
            c.io.cellBus.expect(0.U)
            // Write
            c.io.dataBus.poke(5.U)
            c.io.write.poke(1.U)
            c.io.cellBus.expect(5.U)
            // Verify read-after-write
            c.io.dataBus.poke(12.U)
            c.io.write.poke(0.U)
            c.io.cellBus.expect(5.U)
        }
    }
}

前两个预期与我预期的一样。但是,当我在写入后尝试读取时,cellBus 会返回到0,而不是保留我之前编写的5

test MemCell Success: 0 tests passed in 1 cycles in 0.035654 seconds 28.05 Hz
[info] MemCellTest:
[info] MemCell
[info] - should read and write *** FAILED ***
[info]   io_cellBus=0 (0x0) did not equal expected=5 (0x5) (lines in MyTest.scala: 10) (MyTest.scala:21)

显然寄存器没有保留这个值,所以internalValue 恢复为0。但是为什么会发生这种情况,我如何才能创造出可以持续存在的价值呢?

【问题讨论】:

  • 寄存器的值只会在随后的时钟周期更新,所以一定要在你的pokeexpect之间做step(1)

标签: scala chisel


【解决方案1】:

Drakinite 的评论是正确的。您需要确保步进时钟以查看寄存器锁存值。我调整了您的测试以包含几个步骤,它按预期工作:

  c.io.dataBus.poke(5.U)
  c.io.writeBus.poke(0.U)
  c.io.cellBus.expect(0.U)
  c.clock.step() // Added step
  // Write passthrough (same cycle)
  c.io.dataBus.poke(5.U)
  c.io.writeBus.poke(1.U)
  c.io.cellBus.expect(5.U)
  c.clock.step() // Added step
  // Verify read-after-write
  c.io.dataBus.poke(12.U)
  c.io.writeBus.poke(0.U)
  c.io.cellBus.expect(5.U)

这是一个可执行示例,表明它有效(使用 chisel3 v3.4.4 和 chiseltest v0.3.4):https://scastie.scala-lang.org/5E1rOEsYSzSUrLXZCvoyNA

【讨论】:

  • 是的,那是我错过的一件事。谢谢,我已经盯着那个太久了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 1970-01-01
相关资源
最近更新 更多