diff options
| author | Henry Cook | 2015-11-04 09:21:07 -0800 |
|---|---|---|
| committer | Henry Cook | 2015-11-04 09:21:07 -0800 |
| commit | a3c9680d1e2b84693759747a4779341ba80c4a50 (patch) | |
| tree | e97ab1d8394b0463ec7f600fce7ba278bd68d93a /src/main/scala/Chisel/Driver.scala | |
| parent | 23d15d166d2ed32f8bd9a153a806c09982659011 (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.scala | 141 |
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 + } } |
