簡體   English   中英

ChiselTest:將有符號整數轉換為無符號整數以獲得期望值

[英]ChiselTest: Cast a signed int to unsigned int for an expected value

我無法確定使用新的 ChiselTest 框架將有符號整數轉換為無符號整數以進行單元測試的正確方法。

這是我一直用來對 ALU 進行單元測試的方法(示例是 16 位),問題是它不可擴展:

    test(new ALU) { c =>
    ...
        /* Sub */
        c.io.ctl.poke(Control.ALU_SUB)
        c.io.src0.poke(4321.U)
        c.io.src1.poke(1234.U)
        c.io.out.expect(3087.U)
        c.io.src0.poke(1234.U)
        c.io.src1.poke(4321.U)
        c.io.out.expect("b_1111_0011_1111_0001".U) /* 2's compliment */
    }

這種方法的問題是,當我生成一個 32 位 ALU(它輸出一個無符號整數)時,單元測試將失敗,因為使用上面的 hacky 字符串方法,字符串將零擴展到 32 位......

我想像這樣重寫測試:

test(new ALU) { c =>
    /* Sub */
    c.io.ctl.poke(Control.ALU_SUB)
    c.io.src0.poke(4321.U)
    c.io.src1.poke(1234.U)
    c.io.out.expect(3087.U)
    c.io.src0.poke(1234.U)
    c.io.src1.poke(4321.U)
    c.io.out.expect(-3087.S.asUInt)
}

但是,盡管設計確實很詳細,但我收到以下錯誤:

[error] (run-main-9) chisel3.internal.ChiselException: Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox.
[error] chisel3.internal.ChiselException: Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox.
[error]         at chisel3.internal.throwException$.apply(Error.scala:85)
[error]         at chisel3.internal.Builder$.forcedUserModule(Builder.scala:298)
[error]         at chisel3.internal.Builder$.pushOp(Builder.scala:336)
[error]         at chisel3.SInt.do_asUInt(Bits.scala:925)
[error]         at cpu.alu$.$anonfun$new$2(Main.scala:26)
[error]         at cpu.alu$.$anonfun$new$2$adapted(Main.scala:18)
[error]         at chiseltest.backends.treadle.TreadleBackend.$anonfun$run$1(TreadleBackend.scala:144)
[error]         at chiseltest.internal.ThreadedBackend$TesterThread$$anon$1.$anonfun$run$1(ThreadedBackend.scala:453)
[error]         at chiseltest.backends.treadle.TreadleBackend.doTimescope(TreadleBackend.scala:103)
[error]         at chiseltest.internal.ThreadedBackend$TesterThread$$anon$1.run(ThreadedBackend.scala:453)
[error]         at java.lang.Thread.run(Thread.java:748)
[error] stack trace is suppressed; run last Test / bgRunMain for the full output
[error] Nonzero exit code: 1
[error] (Test / runMain) Nonzero exit code: 1

我想不出解決這個問題的正確方法。 任何幫助將非常感激。

作為參考,ALU 非常簡單,這里是 ALU class:

class ALU extends Module {
  val io = IO(new Bundle {
    val ctl   = Input(UInt(Control.ALU_BITWIDTH))
    val src0  = Input(UInt(Instructions.WORD_SIZE.W))
    val src1  = Input(UInt(Instructions.WORD_SIZE.W))
    val out   = Output(UInt(Instructions.WORD_SIZE.W))
  })

  val shift = io.src1(3,0).asUInt

  /* Lookup the operation to execute */
  io.out := MuxLookup(io.ctl, 0.U, Seq(
    Control.ALU_ADD -> (io.src0 + io.src1),
    Control.ALU_SUB -> (io.src0 - io.src1),
    Control.ALU_AND -> (io.src0 & io.src1),
    Control.ALU_OR  -> (io.src0 | io.src1),
    Control.ALU_XOR -> (io.src0 ^ io.src1),
    Control.ALU_NOT -> (~io.src0),
    Control.ALU_SLL -> (io.src0 << shift),
    Control.ALU_SRL -> (io.src0 >> shift),
  ))
}

這感覺有點惡心,但至少它是可擴展的(也許是一個可能的解決方案?)......我仍然對在測試框架中將 SInt 轉換為 UInt 的最佳方法感興趣。

    /* Sub */
    c.io.ctl.poke(Control.ALU_SUB)
    c.io.src0.poke(4321.U)
    c.io.src1.poke(1234.U)
    c.io.out.expect(3087.U)
    c.io.src0.poke(1234.U)
    c.io.src1.poke(4321.U)
    def bitwidth = 16 // for example
    def max = scala.math.pow(2,bitwidth).toInt
    c.io.out.expect((max-3087).U)

基於@tonysamaritano 的解決方案進行了一些改進。 寫一個獨立的 Scala function 讓它更好看。

ToSInt(x: Int): Int = scala.math.pow(2, bitwidth).toInt - x

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM