diff --git a/.gitignore b/.gitignore index 938d762..3e0e5a5 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ bin/ *.vcd !tester/src/test/resources/*.vhd + +*verilatorSim/ \ No newline at end of file diff --git a/build.sbt b/build.sbt index fcdd64f..a1bfaa2 100644 --- a/build.sbt +++ b/build.sbt @@ -9,4 +9,7 @@ EclipseKeys.withSource := true libraryDependencies ++= Seq( "com.github.spinalhdl" % "spinalhdl-core_2.11" % "latest.release", "com.github.spinalhdl" % "spinalhdl-lib_2.11" % "latest.release" -) \ No newline at end of file +) + +addCompilerPlugin("org.scala-lang.plugins" % "scala-continuations-plugin_2.11.6" % "1.0.2") +scalacOptions += "-P:continuations:enable" diff --git a/src/main/scala/MyCode/TopLevel.scala b/src/main/scala/MyCode/TopLevel.scala index 5a1ba7a..af0c7b7 100644 --- a/src/main/scala/MyCode/TopLevel.scala +++ b/src/main/scala/MyCode/TopLevel.scala @@ -20,7 +20,12 @@ package MyCode import spinal.core._ import spinal.lib._ +import spinal.sim._ +import spinal.core.SimManagedApi._ +import scala.util.Random + +//Hardware definition class MyTopLevel extends Component { val io = new Bundle { val cond0 = in Bool @@ -38,10 +43,62 @@ class MyTopLevel extends Component { io.flag := (counter === 0) | io.cond1 } -object MyTopLevel { +//Generate the MyTopLevel's Verilog +object MyTopLevelVerilog { def main(args: Array[String]) { - SpinalVhdl(new MyTopLevel) - //SpinalVerilog(new MyTopLevel) + SpinalVerilog(new MyTopLevel) } } +//Generate the MyTopLevel's VHDL +object MyTopLevelVhdl { + def main(args: Array[String]) { + SpinalVhdl(new MyTopLevel) + } +} + +//MyTopLevel's testbench +object MyTopLevelSim { + def main(args: Array[String]) { + SimConfig(new MyTopLevel).withWave.doManagedSim{dut => + + //Fork a process to generate the reset and the clock on the dut + fork{ + dut.clockDomain.assertReset() + dut.clockDomain.fallingEdge() + sleep(10) + dut.clockDomain.disassertReset() + sleep(10) + while(true){ + dut.clockDomain.clockToggle() + sleep(5) + } + } + + + var idx = 0 + while(idx < 100){ + //Generate random values to drive the reference model and the dut + val cond0, cond1 = Random.nextBoolean() + val oldState = dut.io.state.toInt + + //Drive the dut inputs + dut.io.cond0 #= cond0 + dut.io.cond1 #= cond1 + + //Wait a rising edge on the clock + dut.clockDomain.waitRisingEdge() + + //Calculate the reference model values + val modelState = if(cond0) (oldState + 1) & 0xFF else oldState + val modelFlag = modelState == 0 || cond1 + + //Check that the dut values match with the reference model ones + assert(dut.io.state.toInt == modelState) + assert(dut.io.flag.toBoolean == modelFlag) + + idx += 1 + } + } + } +}