summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorJack Koenig2020-08-13 21:30:55 -0700
committerGitHub2020-08-13 21:30:55 -0700
commit6ea6f61aa9ed7fa572fb74641a6943a940bd6b82 (patch)
tree6617414fb2fe5e721dc7ea8c9b226af419318d71 /src/test
parent22c92b97beb3711790ea035337345e6e688fcc55 (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.scala12
-rw-r--r--src/test/scala/chisel3/testers/TreadleBackend.scala77
-rw-r--r--src/test/scala/chiselTests/ChiselSpec.scala8
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(),