使用 peekpoketester 戳个别位

Poking individual bits using peekpoketester

我有一个 IO 包,如下所示

val io = IO(new Bundle{
  val test = Input(UInt(32.W))
})

现在我想从测试平台向测试引脚提供输入。我知道我们可以使用 peekpoketesters 来提供这样的输入

poke(dut.io.test, 40.U)

但是有没有办法可以使用 peekpoketester 来设置测试输入引脚的各个位? 例如像这样的

poke(dut.io.test(31,23) , 6.U)

简短的回答是否定的,不直接支持查看输入的特定位,但是使用您可以在此处查看顶级输入这一事实是一个非常简单的解决方法。您可以 运行 并在 scastie here 上测试它。 您可以将其概括为更直接地对输入进行操作,如您的示例所示。 这段代码使用了一种非常快速、肮脏和朴素的位操作方法,但我喜欢在匆忙时使用二进制文本字符串。请注意,这是使用更现代的 chiseltest(与旧的 iotesters 相比),但可以在 iotesters

中使用类似的方法
import chisel3._
import chiseltest._
import chiseltest.experimental.ChiselTestShell

class PassThrough extends Module {
  val io = IO(new Bundle {
    val in = Input(UInt(32.W))
    val out = Output(UInt(32.W))
  })

  io.out := io.in
}

/** use strings to construct bit mask to clear target range and then or in newbits */
def setBits(
    target: BigInt,
    topBit: Int,
    lowBit: Int,
    newBits: BigInt
): BigInt = {
  val clearMask = BigInt(
    "1" * (target.bitLength.max(
      newBits.bitLength
    ) - topBit) + "0" * (topBit - lowBit + 1) + "1" * lowBit,
    radix = 2
  )
  (target & clearMask) | (newBits << lowBit)
}

// crude verification of setBits
println(setBits(BigInt(31), 2, 1, 2).toString(2))

chiseltest.RawTester.test(new PassThrough) { c =>
  c.io.in.poke(40.U)
  c.clock.step()
  c.io.out.expect(40.U)

  val lastIn = c.io.in.peek().litValue()
  val newVal = setBits(lastIn, 31, 23, 6)

  val bitAddr = (0 to 31).map { x => x % 10 }.reverse.mkString("")
  
  println(s"          = $bitAddr")
  println(f"lastIn    = ${lastIn.toString(2)}%32s")
  println(f"newVal    = ${newVal.toString(2)}%32s")
  c.io.in.poke(newVal.U)
  c.clock.step()
  c.io.out.expect(newVal.U)
}