From 72bec2c4774cc78ec2679848517896f3b0c6aab4 Mon Sep 17 00:00:00 2001 From: ducky Date: Wed, 5 Dec 2018 12:01:12 -0800 Subject: [PATCH] writeVcd from command line, test run dir name from test --- .../tester/ChiselScalatestTester.scala | 9 ++++++-- src/main/scala/chisel3/tester/Testers2.scala | 8 ++++--- .../scala/chisel3/tester/TreadleBackend.scala | 21 ++++++++++++------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/scala/chisel3/tester/ChiselScalatestTester.scala b/src/main/scala/chisel3/tester/ChiselScalatestTester.scala index 2780c562b..ca70824c2 100644 --- a/src/main/scala/chisel3/tester/ChiselScalatestTester.scala +++ b/src/main/scala/chisel3/tester/ChiselScalatestTester.scala @@ -88,12 +88,17 @@ trait ChiselScalatestTester extends Assertions with TestSuiteMixin with TestEnvI Context.run(tester, this, testFn) } + def getTestOptions(): TesterOptions = { + val test = scalaTestContext.value.get + TesterOptions(test.name, test.configMap.contains("writeVcd")) + } + // This should be the only user-called function def test[T <: MultiIOModule](dutGen: => T)(testFn: T => Unit) { - runTest(Context.createDefaultTester(() => dutGen, None))(testFn) + runTest(Context.createDefaultTester(() => dutGen, getTestOptions(), None))(testFn) } def test[T <: MultiIOModule](dutGen: => T, execOptions: ExecutionOptionsManager)(testFn: T => Unit) { - runTest(Context.createDefaultTester(() => dutGen, Some(execOptions)))(testFn) + runTest(Context.createDefaultTester(() => dutGen, getTestOptions(), Some(execOptions)))(testFn) } } diff --git a/src/main/scala/chisel3/tester/Testers2.scala b/src/main/scala/chisel3/tester/Testers2.scala index 97c98a90f..5d3c13063 100644 --- a/src/main/scala/chisel3/tester/Testers2.scala +++ b/src/main/scala/chisel3/tester/Testers2.scala @@ -7,7 +7,8 @@ import chisel3.experimental.MultiIOModule import firrtl.ExecutionOptionsManager // Internal common set of options to be understood by all backends -private[tester] case class Testers2Options( +private[tester] case class TesterOptions( + name: String, writeVcd: Boolean ) @@ -26,9 +27,10 @@ object Context { // TODO: better integration points for default tester selection // TODO: add TesterOptions (from chisel-testers) and use that to control default tester selection. - def createDefaultTester[T <: MultiIOModule](dutGen: () => T, execOptions: Option[ExecutionOptionsManager] + def createDefaultTester[T <: MultiIOModule](dutGen: () => T, testOptions: TesterOptions, + execOptions: Option[ExecutionOptionsManager] ): BackendInstance[T] = { - TreadleExecutive.start(dutGen, execOptions) + TreadleExecutive.start(dutGen, testOptions, execOptions) } def apply(): Instance = context.value.get diff --git a/src/main/scala/chisel3/tester/TreadleBackend.scala b/src/main/scala/chisel3/tester/TreadleBackend.scala index de004e442..a2a36c1fb 100644 --- a/src/main/scala/chisel3/tester/TreadleBackend.scala +++ b/src/main/scala/chisel3/tester/TreadleBackend.scala @@ -194,34 +194,39 @@ object TreadleExecutive { def start[T <: MultiIOModule]( dutGen: () => T, - userOptions: Option[ExecutionOptionsManager] = None): BackendInstance[T] = { + testOptions: TesterOptions, + execOptions: Option[ExecutionOptionsManager] = None): BackendInstance[T] = { // Create the base options manager that has all the components we care about, and initialize defaults val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions with HasTreadleSuite - optionsManager.treadleOptions = optionsManager.treadleOptions.copy(writeVCD = true) - // If the user specified options, override the default fields. // Note: commonOptions and firrtlOptions are part of every ExecutionOptionsManager, so will always be defined // whether the user intended to or not. In those cases testers2 forces an override to the testers2 defaults. - userOptions foreach { + execOptions foreach { case userOptions: HasChiselExecutionOptions => optionsManager.chiselOptions = userOptions.chiselOptions case _ => } - optionsManager.commonOptions = optionsManager.commonOptions.copy( - targetDirName = s"test_run_dir/${dutGen.getClass.getName}") - userOptions foreach { + execOptions foreach { case userOptions: HasFirrtlOptions => optionsManager.firrtlOptions = userOptions.firrtlOptions case _ => } optionsManager.firrtlOptions = optionsManager.firrtlOptions.copy(compilerName = "low") - userOptions foreach { + execOptions foreach { case userOptions: HasTreadleSuite => optionsManager.treadleOptions = userOptions.treadleOptions case _ => } + // Tester options take priority over exec options + val testName = testOptions.name.replaceAll(" ", "_").replaceAll("\\W+", "") // sanitize filename + optionsManager.commonOptions = optionsManager.commonOptions.copy( + targetDirName = s"test_run_dir/$testName") + if (testOptions.writeVcd) { + optionsManager.treadleOptions = optionsManager.treadleOptions.copy(writeVCD = true) + } + // Force a cleanup: long SBT runs tend to fail with memory issues System.gc()