summaryrefslogtreecommitdiff
path: root/src/main/scala/Chisel/Driver.scala
diff options
context:
space:
mode:
authorHenry Cook2015-11-04 09:21:07 -0800
committerHenry Cook2015-11-04 09:21:07 -0800
commita3c9680d1e2b84693759747a4779341ba80c4a50 (patch)
treee97ab1d8394b0463ec7f600fce7ba278bd68d93a /src/main/scala/Chisel/Driver.scala
parent23d15d166d2ed32f8bd9a153a806c09982659011 (diff)
Remove Parameters library and refactor Driver.
In addition to removing all the extraneous Driver invocations that created various top-level Parameters instances, this commit also lays the groundwork for stanza-firrtl/verilator based testing of Modules that extend BasicTester. The execution-based tests have been updated accordingly. They will only succeed if firrtl and verilator binaries have been installed. Further work is needed on individual tests to use assertions instead of .io.error.
Diffstat (limited to 'src/main/scala/Chisel/Driver.scala')
-rw-r--r--src/main/scala/Chisel/Driver.scala141
1 files changed, 83 insertions, 58 deletions
diff --git a/src/main/scala/Chisel/Driver.scala b/src/main/scala/Chisel/Driver.scala
index 5247dc0f..64356b21 100644
--- a/src/main/scala/Chisel/Driver.scala
+++ b/src/main/scala/Chisel/Driver.scala
@@ -2,75 +2,100 @@
package Chisel
-import collection.mutable.{ArrayBuffer, HashSet, HashMap, Stack, LinkedHashSet, Queue => ScalaQueue}
-import scala.math.min
+import scala.sys.process._
+import java.io._
trait FileSystemUtilities {
- def createOutputFile(name: String, contents: String) {
- val f = new java.io.FileWriter(name)
- f.write(contents)
- f.close
+ def writeTempFile(pre: String, post: String, contents: String): File = {
+ val t = File.createTempFile(pre, post)
+ val w = new FileWriter(t)
+ w.write(contents)
+ w.close()
+ t
+ }
+
+ // This "fire-and-forgets" the method, which can be lazily read through
+ // a Stream[String], and accumulates all errors on a StringBuffer
+ def sourceFilesAt(baseDir: String): (Stream[String], StringBuffer) = {
+ val buffer = new StringBuffer()
+ val cmd = Seq("find", baseDir, "-name", "*.scala", "-type", "f")
+ val lines = cmd lines_! ProcessLogger(buffer append _)
+ (lines, buffer)
}
}
-object Driver extends FileSystemUtilities {
+trait BackendCompilationUtilities {
+ def makeHarness(template: String => String, post: String)(f: File): File = {
+ val prefix = f.toString.split("/").last
+ val vf = new File(f.toString + post)
+ val w = new FileWriter(vf)
+ w.write(template(prefix))
+ w.close()
+ vf
+ }
- /** Instantiates a ChiselConfig class with the given name and uses it for elaboration */
- def elaborateWithConfigName[T <: Module](
- gen: () => T,
- configClassName: String,
- projectName: Option[String] = None,
- collectConstraints: Boolean = false): Unit = {
- val className = projectName match {
- case Some(pn) => s"$pn.$configClassName"
- case None => configClassName
- }
- val config = try {
- Class.forName(className).newInstance.asInstanceOf[ChiselConfig]
- } catch {
- case e: java.lang.ClassNotFoundException =>
- throwException("Could not find the ChiselConfig subclass you asked for (i.e. \"" +
- className + "\"), did you misspell it?", e)
- }
- elaborateWithConfig(gen, config, collectConstraints)
+ def firrtlToVerilog(prefix: String, dir: File): ProcessBuilder = {
+ Process(
+ Seq("firrtl",
+ "-i", s"$prefix.fir",
+ "-o", s"$prefix.v",
+ "-X", "verilog"),
+ dir)
}
- /** Uses the provided ChiselConfig for elaboration */
- def elaborateWithConfig[T <: Module](
- gen: () => T,
- config: ChiselConfig,
- collectConstraints: Boolean = false): Unit = {
- val world = if(collectConstraints) config.toCollector else config.toInstance
- val p = Parameters.root(world)
- config.topConstraints.foreach(c => p.constrain(c))
- elaborate(gen, p, config)
+ def verilogToCpp(
+ prefix: String,
+ dir: File,
+ vDut: File,
+ cppHarness: File,
+ vH: File): ProcessBuilder =
+ Seq("verilator",
+ "--cc", vDut.toString,
+ "--assert",
+ "--Wno-fatal",
+ "--trace",
+ "-O2",
+ "+define+TOP_TYPE=V"+prefix,
+ "-CFLAGS", s"""-Wno-undefined-bool-conversion -O2 -DTOP_TYPE=V$prefix -include ${vH.toString}""",
+ "-Mdir", dir.toString,
+ "--exe", cppHarness.toString)
+
+ def cppToExe(prefix: String, dir: File): ProcessBuilder =
+ Seq("make", "-C", dir.toString, "-j", "-f", s"V${prefix}.mk", s"V${prefix}")
+
+ def executeExpectingFailure(
+ prefix: String,
+ dir: File,
+ assertionMsg: String = "Assertion failed"): Boolean = {
+ var triggered = false
+ val e = Process(s"./V${prefix}", dir) ! ProcessLogger(line =>
+ triggered = triggered || line.contains(assertionMsg))
+ triggered
}
- /** Elaborates the circuit specified in the gen function, optionally uses
- * a parameter space to supply context-aware values.
- * TODO: Distinguish between cases where we dump to file vs return IR for
- * use by other Drivers.
- */
- private[Chisel] def elaborateWrappedModule[T <: Module](gen: () => T, p: Parameters, c: Option[ChiselConfig]) {
- val ir = Builder.build(gen())
- val name = c match {
- case None => ir.name
- case Some(config) => s"${ir.name}.$config"
- }
- createOutputFile(s"$name.knb", p.getKnobs)
- createOutputFile(s"$name.cst", p.getConstraints)
- createOutputFile(s"$name.prm", ir.parameterDump.getDump)
- createOutputFile(s"$name.fir", ir.emit)
+ def executeExpectingSuccess(prefix: String, dir: File): Boolean = {
+ !executeExpectingFailure(prefix, dir)
}
- def elaborate[T <: Module](gen: () => T): Unit =
- elaborate(gen, Parameters.empty)
- def elaborate[T <: Module](gen: () => T, p: Parameters): Unit =
- elaborateWrappedModule(() => Module(gen())(p), p, None)
- private def elaborate[T <: Module](gen: () => T, p: Parameters, c: ChiselConfig): Unit =
- elaborateWrappedModule(() => Module(gen())(p), p, Some(c))
+
}
-object chiselMain {
- def apply[T <: Module](args: Array[String], gen: () => T, p: Parameters = Parameters.empty): Unit =
- Driver.elaborateWrappedModule(gen, p, None)
+object Driver extends FileSystemUtilities with BackendCompilationUtilities {
+
+ /** Elaborates the Module specified in the gen function into a Circuit
+ *
+ * @param gen a function that creates a Module hierarchy
+ *
+ * @return the resulting Chisel IR in the form of a Circuit (TODO: Should be FIRRTL IR)
+ */
+ def elaborate[T <: Module](gen: () => T): Circuit = Builder.build(Module(gen()))
+
+ def emit[T <: Module](gen: () => T): String = elaborate(gen).emit
+
+ def dumpFirrtl(ir: Circuit, optName: Option[File]): File = {
+ val f = optName.getOrElse(new File(ir.name + ".fir"))
+ val w = new FileWriter(f)
+ w.write(ir.emit)
+ w.close()
+ f
+ }
}