diff options
| author | Jack Koenig | 2020-08-13 21:30:55 -0700 |
|---|---|---|
| committer | GitHub | 2020-08-13 21:30:55 -0700 |
| commit | 6ea6f61aa9ed7fa572fb74641a6943a940bd6b82 (patch) | |
| tree | 6617414fb2fe5e721dc7ea8c9b226af419318d71 /src/test | |
| parent | 22c92b97beb3711790ea035337345e6e688fcc55 (diff) | |
Move treadle dependency to the tests (#1554)
Use inheritance to make TesterDriver Backend API extensible, then define
a TreadleBackend in the test project
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/scala/chisel3/testers/TestUtils.scala | 12 | ||||
| -rw-r--r-- | src/test/scala/chisel3/testers/TreadleBackend.scala | 77 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/ChiselSpec.scala | 8 |
3 files changed, 95 insertions, 2 deletions
diff --git a/src/test/scala/chisel3/testers/TestUtils.scala b/src/test/scala/chisel3/testers/TestUtils.scala new file mode 100644 index 00000000..97cf9190 --- /dev/null +++ b/src/test/scala/chisel3/testers/TestUtils.scala @@ -0,0 +1,12 @@ +// See LICENSE for license details. + +package chisel3.testers + +import TesterDriver.Backend +import firrtl.AnnotationSeq + +object TestUtils { + // Useful because TesterDriver.Backend is chisel3 package private + def containsBackend(annos: AnnotationSeq): Boolean = + annos.collectFirst { case b: Backend => b }.isDefined +} diff --git a/src/test/scala/chisel3/testers/TreadleBackend.scala b/src/test/scala/chisel3/testers/TreadleBackend.scala new file mode 100644 index 00000000..e432ce35 --- /dev/null +++ b/src/test/scala/chisel3/testers/TreadleBackend.scala @@ -0,0 +1,77 @@ +// See LICENSE for license details. + +package chisel3.testers + +import TesterDriver.createTestDirectory +import chisel3._ +import chisel3.stage._ +import firrtl.AnnotationSeq +import firrtl.annotations.NoTargetAnnotation +import firrtl.options.TargetDirAnnotation +import treadle.stage.TreadleTesterPhase +import treadle.executable.StopException +import treadle.{CallResetAtStartupAnnotation, TreadleTesterAnnotation, WriteVcdAnnotation} + +import java.io.File + +case object TreadleBackend extends TesterDriver.Backend { + val MaxTreadleCycles = 10000L + + def execute(t: () => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq(), + nameHint: Option[String] = None): Boolean = { + val generatorAnnotation = chisel3.stage.ChiselGeneratorAnnotation(t) + + // This provides an opportunity to translate from top level generic flags to backend specific annos + var annotationSeq = annotations :+ WriteVcdAnnotation + + // This produces a chisel circuit annotation, a later pass will generate a firrtl circuit + // Can't do both at once currently because generating the latter deletes the former + annotationSeq = (new chisel3.stage.phases.Elaborate).transform(annotationSeq :+ generatorAnnotation) + + val circuit = annotationSeq.collect { case x: ChiselCircuitAnnotation => x }.head.circuit + + val targetName: File = createTestDirectory(circuit.name) + + if (!annotationSeq.exists(_.isInstanceOf[NoTargetAnnotation])) { + annotationSeq = annotationSeq :+ TargetDirAnnotation(targetName.getPath) + } + if (!annotationSeq.exists { case CallResetAtStartupAnnotation => true ; case _ => false }) { + annotationSeq = annotationSeq :+ CallResetAtStartupAnnotation + } + + // This generates the firrtl circuit needed by the TreadleTesterPhase + annotationSeq = (new ChiselStage).run( + annotationSeq ++ Seq(NoRunFirrtlCompilerAnnotation) + ) + + // This generates a TreadleTesterAnnotation with a treadle tester instance + annotationSeq = (new TreadleTesterPhase).transform(annotationSeq) + + val treadleTester = annotationSeq.collectFirst { case TreadleTesterAnnotation(t) => t }.getOrElse( + throw new Exception( + s"TreadleTesterPhase could not build a treadle tester from these annotations" + + annotationSeq.mkString("Annotations:\n", "\n ", "") + ) + ) + + try { + var cycle = 0L + while (cycle < MaxTreadleCycles) { + cycle += 1 + treadleTester.step() + } + throw new ChiselException(s"Treadle backend exceeded MaxTreadleCycles ($MaxTreadleCycles)") + } catch { + case _: StopException => + } + treadleTester.finish + + treadleTester.getStopResult match { + case None => true + case Some(0) => true + case _ => false + } + } +} diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index e50f26e8..eb3ec3e6 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -10,7 +10,7 @@ import chisel3._ import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.testers._ import firrtl.{AnnotationSeq, CommonOptions, EmittedVerilogCircuitAnnotation, ExecutionOptionsManager, FirrtlExecutionFailure, FirrtlExecutionSuccess, HasFirrtlOptions} -import firrtl.annotations.DeletedAnnotation +import firrtl.annotations.{Annotation, DeletedAnnotation} import firrtl.util.BackendCompilationUtilities import java.io.ByteArrayOutputStream import java.security.Permission @@ -26,7 +26,11 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { additionalVResources: Seq[String] = Seq(), annotations: AnnotationSeq = Seq() ): Boolean = { - TesterDriver.execute(() => t, additionalVResources, annotations) + // Change this to enable Treadle as a backend + val defaultBackend = chisel3.testers.TesterDriver.defaultBackend + val hasBackend = TestUtils.containsBackend(annotations) + val annos: Seq[Annotation] = if (hasBackend) annotations else defaultBackend +: annotations + TesterDriver.execute(() => t, additionalVResources, annos) } def assertTesterPasses(t: => BasicTester, additionalVResources: Seq[String] = Seq(), |
