#scala #chisel
#scala #chisel
Вопрос:
У меня возникли проблемы с определением правильного метода преобразования подписанного int в unsigned int для модульного тестирования с использованием новой платформы 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 (который выводит unsigned int ), модульный тест завершится неудачей, потому что строка будет равна нулю до 32 бит, используя описанный выше метод hacky string …
Я бы хотел переписать тест следующим образом:
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 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 amp; 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),
))
}
Комментарии:
1. кстати, моя версия chiseltest настроена на
"chiseltest" -> "0.2.1 "
Ответ №1:
Это кажется немного грубым, но, по крайней мере, оно масштабируемо (может быть, возможное решение?)… Меня все еще интересует наилучший способ преобразования 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)
Ответ №2:
Внесены некоторые улучшения на основе решения @tonysamaritano. Напишите независимую функцию Scala, чтобы она выглядела лучше.
ToSInt(x: Int): Int = scala.math.pow(2, bitwidth).toInt - x
Комментарии:
1. Это намного красивее и удобнее для чтения, хорошее предложение.