summaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
authorJim Lawson2017-02-01 10:28:43 -0800
committerJack Koenig2017-02-01 10:28:43 -0800
commit24ad38ab28b888e73217a5532cac2f0d2b9a4bc2 (patch)
tree12cc4edcd6a4cac3198ce4c6b2fa0fbe4c69f1bf /src/main/scala
parentcd9eca6bc1d56e4b94955e1ce9e038b1a966a30b (diff)
Move backend compilation utilities (#400)
* Move copyResourceToFile() to BackendCompilationUtilities. * Move BackendCompilationUtilities into a firrtl util package. Some of this could be moved into a more general tools package, but since chisel3 already has a dependency on firrtl ... * Push util down into firrtl so as not to conflict with scala.util. * Use new createTestDirectory. Fixes #452.
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/chisel3/Driver.scala120
-rw-r--r--src/main/scala/chisel3/compatibility.scala2
-rw-r--r--src/main/scala/chisel3/testers/TesterDriver.scala17
3 files changed, 8 insertions, 131 deletions
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala
index e88afc1f..b2acc946 100644
--- a/src/main/scala/chisel3/Driver.scala
+++ b/src/main/scala/chisel3/Driver.scala
@@ -4,12 +4,12 @@ package chisel3
import chisel3.internal.firrtl.Emitter
-import scala.sys.process._
import java.io._
import net.jcazevedo.moultingyaml._
import internal.firrtl._
import firrtl._
+import firrtl.util.{ BackendCompilationUtilities => FirrtlBackendCompilationUtilities }
import _root_.firrtl.annotations.AnnotationYamlProtocol._
@@ -18,7 +18,7 @@ import _root_.firrtl.annotations.AnnotationYamlProtocol._
* By default firrtl is automatically run after chisel. an [[ExecutionOptionsManager]]
* is needed to manage options. It can parser command line arguments or coordinate
* multiple chisel toolchain tools options.
- *
+ *
* @example
* {{{
* val optionsManager = new ExecutionOptionsManager("chisel3")
@@ -37,29 +37,7 @@ import _root_.firrtl.annotations.AnnotationYamlProtocol._
*/
import BuildInfo._
-trait BackendCompilationUtilities {
- /** Create a temporary directory with the prefix name. Exists here because it doesn't in Java 6.
- */
- def createTempDirectory(prefix: String): File = {
- val temp = File.createTempFile(prefix, "")
- if (!temp.delete()) {
- throw new IOException(s"Unable to delete temp file '$temp'")
- }
- if (!temp.mkdir()) {
- throw new IOException(s"Unable to create temp directory '$temp'")
- }
- temp
- }
-
- 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
- }
-
+trait BackendCompilationUtilities extends FirrtlBackendCompilationUtilities {
/** Compile Chirrtl to Verilog by invoking Firrtl inside the same JVM
*
* @param prefix basename of the file
@@ -77,98 +55,6 @@ trait BackendCompilationUtilities {
case _: FirrtlExecutionFailure => false
}
}
-
- /** Compile Chirrtl to Verilog by invoking Firrtl on the command line
- *
- * @param prefix basename of the file
- * @param dir directory where file lives
- * @return external process that can invoke Firrtl
- */
- @deprecated("Use compileFirrtlToVerilog instead", "chisel3")
- def firrtlToVerilog(prefix: String, dir: File): ProcessBuilder = {
- Process(
- Seq("firrtl",
- "-i", s"$prefix.fir",
- "-o", s"$prefix.v",
- "-X", "verilog"),
- dir)
- }
-
- /** Generates a Verilator invocation to convert Verilog sources to C++
- * simulation sources.
- *
- * The Verilator prefix will be V\$dutFile, and running this will generate
- * C++ sources and headers as well as a makefile to compile them.
- *
- * @param dutFile name of the DUT .v without the .v extension
- * @param topModule of the top-level module in the design
- * @param dir output directory
- * @param vSources list of additional Verilog sources to compile
- * @param cppHarness C++ testharness to compile/link against
- */
- def verilogToCpp(
- dutFile: String,
- topModule: String,
- dir: File,
- vSources: Seq[File],
- cppHarness: File
- ): ProcessBuilder = {
- val blackBoxVerilogList = {
- val list_file = new File(dir, firrtl.transforms.BlackBoxSourceHelper.FileListName)
- if(list_file.exists()) {
- Seq("-f", list_file.getAbsolutePath)
- }
- else {
- Seq.empty[String]
- }
- }
- val command = Seq(
- "verilator",
- "--cc", s"$dutFile.v"
- ) ++
- blackBoxVerilogList ++
- vSources.map(file => Seq("-v", file.toString)).flatten ++
- Seq(
- "--assert",
- "-Wno-fatal",
- "-Wno-WIDTH",
- "-Wno-STMTDLY",
- "--trace",
- "-O1",
- "--top-module", topModule,
- "+define+TOP_TYPE=V" + dutFile,
- s"+define+PRINTF_COND=!$topModule.reset",
- s"+define+STOP_COND=!$topModule.reset",
- "-CFLAGS",
- s"""-Wno-undefined-bool-conversion -O1 -DTOP_TYPE=V$dutFile -DVL_USER_FINISH -include V$dutFile.h""",
- "-Mdir", dir.toString,
- "--exe", cppHarness.toString)
- System.out.println(s"${command.mkString(" ")}") // scalastyle:ignore regex
- command
- }
-
- 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 = ""): Boolean = {
- var triggered = false
- val assertionMessageSupplied = assertionMsg != ""
- val e = Process(s"./V${prefix}", dir) !
- ProcessLogger(line => {
- triggered = triggered || (assertionMessageSupplied && line.contains(assertionMsg))
- System.out.println(line) // scalastyle:ignore regex
- })
- // Fail if a line contained an assertion or if we get a non-zero exit code
- // or, we get a SIGABRT (assertion failure) and we didn't provide a specific assertion message
- triggered || (e != 0 && (e != 134 || !assertionMessageSupplied))
- }
-
- def executeExpectingSuccess(prefix: String, dir: File): Boolean = {
- !executeExpectingFailure(prefix, dir)
- }
}
/**
diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala
index d7ce7f24..d338d9ab 100644
--- a/src/main/scala/chisel3/compatibility.scala
+++ b/src/main/scala/chisel3/compatibility.scala
@@ -177,7 +177,7 @@ package object Chisel { // scalastyle:ignore package.object.name
implicit class fromBooleanToLiteral(val x: Boolean) extends chisel3.core.fromBooleanToLiteral(x)
implicit class fromIntToWidth(val x: Int) extends chisel3.core.fromIntToWidth(x)
- type BackendCompilationUtilities = chisel3.BackendCompilationUtilities
+ type BackendCompilationUtilities = firrtl.util.BackendCompilationUtilities
val Driver = chisel3.Driver
val ImplicitConversions = chisel3.util.ImplicitConversions
diff --git a/src/main/scala/chisel3/testers/TesterDriver.scala b/src/main/scala/chisel3/testers/TesterDriver.scala
index bcbb9cd3..fd3ad9ba 100644
--- a/src/main/scala/chisel3/testers/TesterDriver.scala
+++ b/src/main/scala/chisel3/testers/TesterDriver.scala
@@ -5,18 +5,9 @@ package chisel3.testers
import chisel3._
import java.io._
+import firrtl.{Driver => _, _}
+
object TesterDriver extends BackendCompilationUtilities {
- /** Copy the contents of a resource to a destination file.
- */
- def copyResourceToFile(name: String, file: File) {
- val in = getClass.getResourceAsStream(name)
- if (in == null) {
- throw new FileNotFoundException(s"Resource '$name'")
- }
- val out = new FileOutputStream(file)
- Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write)
- out.close()
- }
/** For use with modules that should successfully be elaborated by the
* frontend, and which can be turned into executables with assertions. */
@@ -29,7 +20,7 @@ object TesterDriver extends BackendCompilationUtilities {
// plus the quirks of Verilator's naming conventions
val target = circuit.name
- val path = createTempDirectory(target)
+ val path = createTestDirectory(target)
val fname = new File(path, target)
// For now, dump the IR out to a file
@@ -50,7 +41,7 @@ object TesterDriver extends BackendCompilationUtilities {
return false
}
// Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe
- if ((verilogToCpp(target, target, path, additionalVFiles, cppHarness) #&&
+ if ((verilogToCpp(target, path, additionalVFiles, cppHarness) #&&
cppToExe(target, path)).! == 0) {
executeExpectingSuccess(target, path)
} else {