I am trying to come up with a better title.
I am new in Chisel and Scala. Below there is a Chisel code defining and testing an module.
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
class DeviceUnderTest extends Module {
val io = IO(new Bundle {
val a = Input(UInt(2.W))
val b = Input(UInt(2.W))
val out = Output(UInt(2.W))
})
io.out := io.a & io.b
}
class WaveformTestWithIteration extends AnyFlatSpec with ChiselScalatestTester {
"WaveformIteration" should "pass" in {
test(new DeviceUnderTest)
.withAnnotations(Seq(WriteVcdAnnotation)) ( dut => // ???
{
for (a <- 0 until 4; b <- 0 until 4) {
dut.io.a.poke(a.U)
dut.io.b.poke(b.U)
dut.clock.step()
}
}
)
}
}
The code line with comments ??? is where I am quite puzzled. Where does the variable dut is defined? It seems an reference to instance gained by new DeviceUnderTest.
test(new DeviceUnderTest).withAnnotations(Seq(WriteVcdAnnotation)) return an TestBuilder[T] with apply method:
class TestBuilder[T <: Module](...) {
...
def apply(testFn: T => Unit): TestResult = {
runTest(defaults.createDefaultTester(dutGen, finalAnnos))(testFn)
}
...
}
So, dut => {...} is a function (T) => Unit? But it does not look like a standard lambda ((x:T) => {...})? Or it is something else?
What is this syntax in scala exactly?
Consider the following boiled-down version with a similar structure:
What it's essentially doing is taking a value
x: Aand a functionf: A => Unit, and applyingftoxto obtainf(x).Here is how you could use it:
In both cases, the "string under test" is simply passed to the body of the "test".
Now, you could introduce a few more steps between the creation of the value under test and the specification of the body. For example, you could create a
TestBuilder[A], which is essentially just a valueawith some bells and whistles (in this case, list of "annotations" - plain strings in the following example):The principle remains the same:
test(a)saves the tested valuea, thenTestBuilderadds some configuration, and once you add a body{ thingUnderTest => /* assertStuff */ }to it, you get a fullTest, which you can thenrunto obtain some results (TestOutcomes, in this case). Thus, the above snippet produces