How can I test a Chisel3 BlackBox?

386 Views Asked by At

I have the following test harness for a module defined in Verilog:

class TestMCQDiv extends FlatSpec with ChiselScalatestTester with Matchers {
    behavior of "MCQDiv"

    // Dependent Variables for Testing
    val integerWidth = 50
    val rationalWidth = 10
    val bitWidth = integerWidth + rationalWidth

    // Module and Test Dependencies
    val fepar = new UFSMulticycleConstraints(integerWidth, rationalWidth)

    //val scale = 124.0
    val scale = 1.0
    val i = 36.0
    val n = 2.0

    it should "Test the MCQDiv Module" in {
        test(new mc_qdiv(fepar)) { dut =>
            // iterate through each test value
            for (t <- -7 to -7) {
                // Initialize each value
                dut.io.i_dividend.poke(1.S(15.W))
                dut.io.i_divisor.poke(1.S(15.W))
                dut.io.i_start.poke(1.B)

                while(dut.io.o_complete.peek().litValue().toDouble == 0) {
                    dut.io.i_clk.step(1)
                }
                println("Test( " + t + " / " + 1 + " ) = " + dut.io.o_quotient_out.peek())

            }
        }
    }
}

The implementation for MCQDiv has been defined here:

class qdiv(fepar: UFSMulticycleConstraints) extends BlackBox with HasBlackBoxResource {
    val io = IO(new Bundle{
        val i_dividend: SInt = Input(SInt(fepar.bit_width.W))
        val i_divisor: SInt = Input(SInt(fepar.bit_width.W))
        val i_start: Bool = Input(Bool())
        val i_clk: Clock = Input(Clock())
        val o_quotient_out: SInt = Output(SInt(fepar.bit_width.W))
        val o_complete: Bool = Output(Bool())
        val o_overflow: Bool = Output(Bool())
    })

    addResource("/mc_qdiv.v")
}

class mc_qdiv(fepar: UFSMulticycleConstraints) extends Module {
    val io = IO(new Bundle {
        val i_dividend: SInt = Input(SInt(fepar.bit_width.W))
        val i_divisor: SInt = Input(SInt(fepar.bit_width.W))
        val i_start: Bool = Input(Bool())
        val i_clk: Clock = Input(Clock())
        val o_quotient_out: SInt = Output(SInt(fepar.bit_width.W))
        val o_complete: Bool = Output(Bool())
        val o_overflow: Bool = Output(Bool())
    })

    val bb_qdiv: qdiv = Module(new qdiv(fepar))

    bb_qdiv.io.i_dividend := io.i_dividend
    bb_qdiv.io.i_divisor := io.i_divisor
    bb_qdiv.io.i_start := io.i_start
    bb_qdiv.io.i_clk := io.i_clk
    io.o_quotient_out := bb_qdiv.io.o_quotient_out
    io.o_complete := bb_qdiv.io.o_complete
    io.o_overflow := bb_qdiv.io.o_overflow

}

Initially, I was facing an issue where the Verilog module couldn't be found:

WARNING: external module "qdiv"(:qdiv)was not matched with an implementation.

The following site led me to realize the backend compiler needed to be changed to Verilator. Following the instructions posted there, I was able to eliminate the prior warning by adding the following flag to my compiler command: -z verilator. The full command looks like this: sbt 'testOnly Exp.TestMCQDiv -- -z verilator' Now the compilation (incorrectly) completes without executing any tests. I did try looking through an example BlackBox implementation on Github, however, there was no example using peek-poke testing and I very much would like to use that. Is there something fundamental to Chisel that I may be forgetting (I am new to Chisel)? Or would anyone know what specifically I'm doing wrong?

Additional Information: I do have Verilator installed: Verilator 4.106 2020-12-02 rev v4.104-91-gb350b6a0f. I'm also using Chisel3.

1

There are 1 best solutions below

0
On

-z is scalatest switch for filtering the tests to run. If you don’t have any tests matching that name nothing will run. (You can check out the full list of scalatest command line arguments in the scalatest docs: https://www.scalatest.org/user_guide/using_the_runner) You can select chiseltest Verilator backend using VerilatorBackendAnnotation. See an example here: https://github.com/ucb-bar/chiseltest/blob/master/src/test/scala/chiseltest/iotesters/examples/GCDSpec.scala