import chisel3._ import chisel3.iotesters._ // PeakPokeTester is imported by this
clase DeviceUnderTestextendsModule{ val io = IO(newBundle{ val a = Input(UInt(2.W)) val b = Input(UInt(2.W)) val out = Output(UInt(2.W)) }) io.out := io.a & io.b }
然后再设计一个testbench(这里使用到了 chisel3.iotesters 库):
1 2 3 4 5 6 7 8 9 10
classTesterSample(dut: DeviceUnderTest) extendsPeekPokeTester(dut){ poke(dut.io.a, 0.U) poke(dut.io.b, 1.U) step(1) // run 1 clk cycle println("Result is " + peek(dut.io.out).toString) poke(dut.io.a, 2.U) poke(dut.io.b, 3.U) step(1) // run another clk cycle println("Result is " + peek(dut.io.out).toString) }
最后,运行这个测试单元:
1 2 3 4 5
classTesterSampleextendsApp{ chisel3.iotester.Driver(() => newDeviceUnderTest()){ c => newTesterSample(c) } }
输出将打印peek的结构到屏幕上,同时,如果需要检查特定的值,可以调用expect:
1 2 3 4 5 6 7 8 9 10
classTesterSample(dut: DeviceUnderTest) extendsPeekPokeTester(dut){ poke(dut.io.a, 0.U) poke(dut.io.b, 1.U) step(1) // run 1 clk cycle expect(dut.io.out, 0) poke(dut.io.a, 2.U) poke(dut.io.b, 3.U) step(1) // run another clk cycle expect(dut.io.out, 2) }
// this is normal scala test import org.scalatest._ classExampleSpecextendsFlatSpecwithMatchers{ "Intergers" should "add" in { val i = 2 val j = 3 i + j should be (5) } } // this is chisel test classSimpleSpecextendsFlatSpecwithMatchers{ "Tester" should "pass" in { chisel3.iotester.Driver(() => newDeviceUnderTest()) { c => newTester(c) } should be (true) } }
使用sbt test的时候将会运行上面所有测试,如果想只运行下面的可以带上参数:
1
sbt "testOnly SimpleSpec"
波形输出
波形文件的输出需要额外导入Driver:
1
import chisel3.iotesters.Dirver
使用方式:
1 2 3 4 5 6 7
classWaveformSpecextendsFlatSpecwithMatchers{ "Waveform" should "pass" in { // what is this line's meaning? Driver.excute(Array("--generate-vcd-output", "on"), () => newDeviceUnderTest()) { // DeviceUndetTest is a Class c => newWaveFormTester(c) // WFT is a testbench } should be (true) } }
classCompAextendsModule{ val io = IO(newBundle { val a_i = Input(UInt(8.W)) val b_i = Input(UInt(8.W)) val x_o = Output(UInt(8.W)) val y_o = Output(UInt(8.W)) }) // Implentation }
classCompBextendsModule{ val io = IO(newBundle { val a_i = Input(UInt(8.W)) val b_i = Input(UInt(8.W)) val x_o = Output(UInt(8.W)) }) // Implentation }
classCompCextendsModule{ val io = IO(newBundle { val a_i = Input(UInt(8.W)) val b_i = Input(UInt(8.W)) val c_i = Input(UInt(8.W)) val x_o = Output(UInt(8.W)) val y_o = Output(UInt(8.W)) })
val compA = newCompA() val compB = newCompB()
// input // Atention!!! do not code this wrong direciton, such as // io.a_i := compA.io.a_i compA.io.a_i := io.a_i compA.io.b_i := io.b_i compB.io.b_i := io.c_i
classCompDextendsModule{ val io = IO(newBundle { val in = Input(UInt(8.W)) val out = Output(UInt(8.W)) }) // Implentation }
classTopLevelextendsModule{ val io = IO(newBundle { val a_i = Input(UInt(8.W)) val b_i = Input(UInt(8.W)) val c_i = Input(UInt(8.W)) val m_o = Output(UInt(8.W)) val n_o = Output(UInt(8.W)) })