From 7e5aef460e089b3dfd53ddd181f9384cc25145d7 Mon Sep 17 00:00:00 2001 From: jackkoenig Date: Tue, 20 Sep 2016 16:12:59 -0700 Subject: Add Cookbook tests These tests are intended to be the examples in the Chisel3 Wiki Cookbook. --- src/test/scala/cookbook/Bundle2UInt.scala | 31 ++++++++++++++++++++++++++++ src/test/scala/cookbook/CookbookSpec.scala | 25 ++++++++++++++++++++++ src/test/scala/cookbook/UInt2Bundle.scala | 30 +++++++++++++++++++++++++++ src/test/scala/cookbook/UInt2VecOfBool.scala | 29 ++++++++++++++++++++++++++ src/test/scala/cookbook/VecOfBool2UInt.scala | 28 +++++++++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 src/test/scala/cookbook/Bundle2UInt.scala create mode 100644 src/test/scala/cookbook/CookbookSpec.scala create mode 100644 src/test/scala/cookbook/UInt2Bundle.scala create mode 100644 src/test/scala/cookbook/UInt2VecOfBool.scala create mode 100644 src/test/scala/cookbook/VecOfBool2UInt.scala diff --git a/src/test/scala/cookbook/Bundle2UInt.scala b/src/test/scala/cookbook/Bundle2UInt.scala new file mode 100644 index 00000000..d74218a8 --- /dev/null +++ b/src/test/scala/cookbook/Bundle2UInt.scala @@ -0,0 +1,31 @@ +// See LICENSE for license details. + +package cookbook + +import chisel3._ + +/* ### How do I create a UInt from an instance of a Bundle? + * + * Call asUInt on the Bundle instance + */ +class Bundle2UInt extends CookbookTester(0) { + // Example + class MyBundle extends Bundle { + val foo = UInt(width = 4) + val bar = UInt(width = 4) + } + val bundle = Wire(new MyBundle) + bundle.foo := UInt(0xc) + bundle.bar := UInt(0x3) + val uint = bundle.asUInt + printf(p"$uint") // 195 + + // Test + assert(uint === UInt(0xc3)) +} + +class Bundle2UIntSpec extends CookbookSpec { + "Bundle2UInt" should "work" in { + assertTesterPasses { new Bundle2UInt } + } +} diff --git a/src/test/scala/cookbook/CookbookSpec.scala b/src/test/scala/cookbook/CookbookSpec.scala new file mode 100644 index 00000000..b244f3cf --- /dev/null +++ b/src/test/scala/cookbook/CookbookSpec.scala @@ -0,0 +1,25 @@ +// See LICENSE for license details. + +package cookbook + +import chisel3._ +import chisel3.util._ +import chisel3.testers.BasicTester + +import chiselTests.ChiselFlatSpec + +/** Tester for concise cookbook tests + * + * Provides a length of test after which the test will pass + */ +abstract class CookbookTester(length: Int) extends BasicTester { + require(length >= 0, "Simulation length must be non-negative!") + + // No IO allowed, cookbook tests must be self-contained + override final val io = new Bundle { } + + val (cycle, done) = Counter(Bool(true), length) + when (done) { stop() } +} + +abstract class CookbookSpec extends ChiselFlatSpec diff --git a/src/test/scala/cookbook/UInt2Bundle.scala b/src/test/scala/cookbook/UInt2Bundle.scala new file mode 100644 index 00000000..fbf7fe8a --- /dev/null +++ b/src/test/scala/cookbook/UInt2Bundle.scala @@ -0,0 +1,30 @@ +// See LICENSE for license details. + +package cookbook + +import chisel3._ + +/* ### How do I create a Bundle from a UInt? + * + * On an instance of the Bundle, call the method fromBits with the UInt as the argument + */ +class UInt2Bundle extends CookbookTester(0) { + // Example + class MyBundle extends Bundle { + val foo = UInt(width = 4) + val bar = UInt(width = 4) + } + val uint = UInt(0xb4) + val bundle = (new MyBundle).fromBits(uint) + printf(p"$bundle") // Bundle(foo -> 11, bar -> 4) + + // Test + assert(bundle.foo === UInt(0xb)) + assert(bundle.bar === UInt(0x4)) +} + +class UInt2BundleSpec extends CookbookSpec { + "UInt2Bundle" should "work" in { + assertTesterPasses { new UInt2Bundle } + } +} diff --git a/src/test/scala/cookbook/UInt2VecOfBool.scala b/src/test/scala/cookbook/UInt2VecOfBool.scala new file mode 100644 index 00000000..ad4a0334 --- /dev/null +++ b/src/test/scala/cookbook/UInt2VecOfBool.scala @@ -0,0 +1,29 @@ +// See LICENSE for license details. + +package cookbook + +import chisel3._ + +/* ### How do I create a Vec of Bools from a UInt? + * + * Use the builtin function [[chisel3.core.Bits.toBools]] to create a Scala Seq of Bool, + * then wrap the resulting Seq in Vec(...) + */ +class UInt2VecOfBool extends CookbookTester(0) { + // Example + val uint = UInt(0xc) + val vec = Vec(uint.toBools) + printf(p"$vec") // Vec(0, 0, 1, 1) + + // Test + assert(vec(0) === Bool(false)) + assert(vec(1) === Bool(false)) + assert(vec(2) === Bool(true)) + assert(vec(3) === Bool(true)) +} + +class UInt2VecOfBoolSpec extends CookbookSpec { + "UInt2VecOfBool" should "work" in { + assertTesterPasses { new UInt2VecOfBool } + } +} diff --git a/src/test/scala/cookbook/VecOfBool2UInt.scala b/src/test/scala/cookbook/VecOfBool2UInt.scala new file mode 100644 index 00000000..5852120c --- /dev/null +++ b/src/test/scala/cookbook/VecOfBool2UInt.scala @@ -0,0 +1,28 @@ +// See LICENSE for license details. + +package cookbook + +import chisel3._ + +/* ### How do I create a UInt from a Vec of Bool? + * + * Use the builtin function asUInt + */ +class VecOfBool2UInt extends CookbookTester(0) { + // Example + val vec = Vec(Bool(true), Bool(false), Bool(true), Bool(true)) + val uint = vec.asUInt + printf(p"$uint") // 13 + + /* Test + * + * (remember leftmost Bool in Vec is low order bit) + */ + assert(UInt(0xd) === uint) +} + +class VecOfBool2UIntSpec extends CookbookSpec { + "VecOfBool2UInt" should "work" in { + assertTesterPasses { new VecOfBool2UInt } + } +} -- cgit v1.2.3 From 510edad0f7446b4a422c4dfd070054dd25f44233 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 27 Sep 2016 09:32:09 -0700 Subject: Use "chisel3" as sbt project name. --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 02a0e9f5..de4ad539 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,7 @@ lazy val commonSettings = Seq ( ) lazy val chiselSettings = Seq ( - name := "Chisel3", + name := "chisel3", publishMavenStyle := true, publishArtifact in Test := false, -- cgit v1.2.3 From f1507aa7cec86ca8f5de13ddc96fd046370dfe1d Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 30 Sep 2016 15:22:19 -0700 Subject: clone firrtlDirection when cloning --- chiselFrontend/src/main/scala/chisel3/core/Data.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 3f21a34c..867c5a16 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -163,6 +163,7 @@ abstract class Data extends HasId { //TODO(twigg): Do recursively for better error messages for((clone_elem, source_elem) <- clone.allElements zip this.allElements) { clone_elem.binding = UnboundBinding(source_elem.binding.direction) + Data.setFirrtlDirection(clone_elem, Data.getFirrtlDirection(source_elem)) } clone } -- cgit v1.2.3 From 1abe52da025c3935c28d0280abbadf40021d5b3f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 4 Oct 2016 11:02:14 -0700 Subject: Generate a better error message for missing IO() wrapper - fix #305 --- .../src/main/scala/chisel3/core/Binding.scala | 36 ++++++++++++++++++++-- src/test/scala/chiselTests/IOCompatibility.scala | 16 +++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala index 5378f3ae..467cb4eb 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala @@ -53,6 +53,7 @@ object Binding { case class BindingException(message: String) extends Exception(message) def AlreadyBoundException(binding: String) = BindingException(s": Already bound to $binding") def NotSynthesizableException = BindingException(s": Not bound to synthesizable node, currently only Type description") + def MissingIOWrapperException = BindingException(": Missing IO() wrapper") // This recursively walks down the Data tree to look at all the leaf 'Element's // Will build up an error string in case something goes wrong @@ -138,6 +139,29 @@ object Binding { } } } + + /** Diagnose a binding error caused by a missing IO() wrapper. + * @param element the element triggering the binding error. + * @return true if the element is a member of the module's io but ioDefined is false. + */ + def isMissingIOWrapper(element: Element): Boolean = { + element._parent match { + case None => false + case Some(x: Module) => { + // If the IO() wrapper has been executed, it isn't missing. + if (x.ioDefined) { + false + } else { + // TODO: We should issue the message only once, and if we get here, + // we know the wrapper is missing, whether or not the element is a member of io. + // But if it's not an io element, we want to issue the complementary "unbound" error. + // Revisit this when we collect error messages instead of throwing exceptions. + x.io.flatten.contains(element) + } + } + } + } + try walkToBinding( target, element => element.binding match { @@ -145,10 +169,16 @@ object Binding { case binding => // The following kludge is an attempt to provide backward compatibility // It should be done at at higher level. - if ((forcedModule.compileOptions.requireIOWrap || !elementOfIO(element))) - throw NotSynthesizableException - else + if ((forcedModule.compileOptions.requireIOWrap || !elementOfIO(element))) { + // Generate a better error message if this is a result of a missing IO() wrapper. + if (isMissingIOWrapper(element)) { + throw MissingIOWrapperException + } else { + throw NotSynthesizableException + } + } else { Binding.bind(element, PortBinder(element._parent.get), "Error: IO") + } } ) catch { diff --git a/src/test/scala/chiselTests/IOCompatibility.scala b/src/test/scala/chiselTests/IOCompatibility.scala index 7bf3dded..552fe776 100644 --- a/src/test/scala/chiselTests/IOCompatibility.scala +++ b/src/test/scala/chiselTests/IOCompatibility.scala @@ -3,6 +3,8 @@ package chiselTests import chisel3._ +import chisel3.core.Binding.BindingException +import org.scalatest._ class IOCSimpleIO extends Bundle { val in = Input(UInt(width=32)) @@ -33,7 +35,7 @@ class IOCModuleWire extends Module { io.out := inc.out } -class IOCompatibilitySpec extends ChiselPropSpec { +class IOCompatibilitySpec extends ChiselPropSpec with Matchers { property("IOCModuleVec should elaborate") { elaborate { new IOCModuleVec(2) } @@ -42,4 +44,16 @@ class IOCompatibilitySpec extends ChiselPropSpec { property("IOCModuleWire should elaborate") { elaborate { new IOCModuleWire } } + + + class IOUnwrapped extends Module { + val io = new IOCSimpleIO + io.out := io.in + } + + property("Unwrapped IO should generate an exception") { + a [BindingException] should be thrownBy { + elaborate(new IOUnwrapped) + } + } } -- cgit v1.2.3 From ffe58abac5f60d785b684bb249aee0153bddea3f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 19 Sep 2016 15:27:52 -0700 Subject: Add sbt-buildinfo support. --- build.sbt | 19 +++++++++++++++++++ project/plugins.sbt | 2 ++ src/main/scala/chisel3/Driver.scala | 4 ++++ src/test/scala/chiselTests/BuildInfoTests.scala | 13 +++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 src/test/scala/chiselTests/BuildInfoTests.scala diff --git a/build.sbt b/build.sbt index 02a0e9f5..fe22c95a 100644 --- a/build.sbt +++ b/build.sbt @@ -93,6 +93,25 @@ lazy val chiselFrontend = (project in file("chiselFrontend")). dependsOn(coreMacros) lazy val chisel = (project in file(".")). + enablePlugins(BuildInfoPlugin). + settings( + // We should really be using name.value, but currently, the package is "Chisel" (uppercase first letter) + buildInfoPackage := /* name.value */ "chisel3", + buildInfoOptions += BuildInfoOption.BuildTime, + buildInfoKeys := Seq[BuildInfoKey](buildInfoPackage, version, scalaVersion, sbtVersion), + // Move the managed source directory where git won't complain about it, + // and where we can easily package its files as part of the source jar artifact. + // We'd like to use versionToArray(), slice(), and mkString() to convert an explicit + // Scala version (like 2.10.6), into the leftmost two components (2.10), + // but this seems to run afoul of assumptions sbt makes about the inclusion + // of Scala-version-specfic code (we get + // BuildInfo is already defined as case class BuildInfo + // so use the full version spec. + //sourceManaged in Compile <<= (sourceDirectory in Compile, scalaVersion){ (s,v) => s / ("scala-" + versionToArray(v).slice(0,2).mkString(".") + "/src_managed") }, + sourceManaged in Compile <<= (sourceDirectory in Compile, scalaVersion){ (s,v) => s / ("scala-" + v + "/src_managed") }, + // Add the generated sources to the packagedSrc artifact since they are excluded by default. + mappings in (Compile, packageSrc) += { ((sourceManaged in Compile).value / "sbt-buildinfo" / "BuildInfo.scala") -> "BuildInfo.scala" } + ). settings(commonSettings: _*). settings(chiselSettings: _*). dependsOn(coreMacros). diff --git a/project/plugins.sbt b/project/plugins.sbt index 585435a0..70e12de8 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -13,3 +13,5 @@ addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5") addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.4") addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.2") + +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 5e0a3a0f..2216bbbd 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -7,6 +7,7 @@ import java.io._ import internal._ import internal.firrtl._ +import BuildInfo._ trait BackendCompilationUtilities { /** Create a temporary directory with the prefix name. Exists here because it doesn't in Java 6. @@ -132,4 +133,7 @@ object Driver extends BackendCompilationUtilities { } def targetDir(): String = { target_dir getOrElse new File(".").getCanonicalPath } + + val version = BuildInfo.version + val chiselVersionString = BuildInfo.toString } diff --git a/src/test/scala/chiselTests/BuildInfoTests.scala b/src/test/scala/chiselTests/BuildInfoTests.scala new file mode 100644 index 00000000..21eae17c --- /dev/null +++ b/src/test/scala/chiselTests/BuildInfoTests.scala @@ -0,0 +1,13 @@ +package chiselTests + +import org.scalatest.FlatSpec + +//import Chisel._ + +class BuildInfoTests extends FlatSpec { + behavior of "BuildInfoTests" + + it should "provide correct BuildInfo" in { + println(Chisel.Driver.chiselVersionString) + } +} -- cgit v1.2.3 From f98171296f821034cf66ace070bcf179183e833d Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 5 Oct 2016 09:25:07 -0700 Subject: Print Chisel version when Driver object is created. --- src/main/scala/chisel3/Driver.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 2216bbbd..e91b40b4 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -136,4 +136,5 @@ object Driver extends BackendCompilationUtilities { val version = BuildInfo.version val chiselVersionString = BuildInfo.toString + println(chiselVersionString) } -- cgit v1.2.3 From 2979cb900c4f6773210dbe174091c08e13e6c52a Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 09:21:03 -0700 Subject: Update Driver: Check the simulation exit code #281 Merge with master and support checking for failure with an explicit assertion message. --- src/main/scala/chisel3/Driver.scala | 9 ++++++--- src/test/scala/chiselTests/MultiAssign.scala | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 5e0a3a0f..190b36bf 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -86,14 +86,17 @@ trait BackendCompilationUtilities { def executeExpectingFailure( prefix: String, dir: File, - assertionMsg: String = "Assertion failed"): Boolean = { + assertionMsg: String = ""): Boolean = { var triggered = false + val assertionMessageSupplied = assertionMsg != "" val e = Process(s"./V${prefix}", dir) ! ProcessLogger(line => { - triggered = triggered || line.contains(assertionMsg) + triggered = triggered || (assertionMessageSupplied && line.contains(assertionMsg)) System.out.println(line) // scalastyle:ignore regex }) - triggered + // 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 = { diff --git a/src/test/scala/chiselTests/MultiAssign.scala b/src/test/scala/chiselTests/MultiAssign.scala index fa4c4898..397ea4c2 100644 --- a/src/test/scala/chiselTests/MultiAssign.scala +++ b/src/test/scala/chiselTests/MultiAssign.scala @@ -9,7 +9,8 @@ import chisel3.testers.BasicTester import chisel3.util._ class LastAssignTester() extends BasicTester { - val cnt = Counter(2) + val countOnClockCycles = Bool(true) + val (cnt, wrap) = Counter(countOnClockCycles,2) val test = Wire(UInt.width(4)) assert(test === 7.U) // allow read references before assign references @@ -20,7 +21,7 @@ class LastAssignTester() extends BasicTester { test := 7.U assert(test === 7.U) // this obviously should work - when(cnt.value === 1.U) { + when(cnt === 1.U) { stop() } } -- cgit v1.2.3 From a5aba40349e290c30280df25bc5b0ba848183469 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 10:40:10 -0700 Subject: Add comments; correct Complex definition (use cloneType). --- chiselFrontend/src/main/scala/chisel3/core/Data.scala | 12 ++++++++++++ src/test/scala/chiselTests/ComplexAssign.scala | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 867c5a16..e95b4352 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -155,7 +155,19 @@ abstract class Data extends HasId { private[chisel3] def toType: String private[core] def width: Width + /** cloneType must be defined for any Chisel object extending Data. + * It is responsible for constructing a basic copy of the object being cloned. + * If cloneType needs to recursively clone elements of an object, it should call + * the cloneType methods on those elements. + * @return a copy of the object. + */ def cloneType: this.type + + /** chiselCloneType is called at the top-level of a clone chain. + * It calls the client's cloneType() method to construct a basic copy of the object being cloned, + * then performs any fixups required to reconstruct the appropriate core state of the cloned object. + * @return a copy of the object with appropriate core state. + */ def chiselCloneType: this.type = { // Call the user-supplied cloneType method val clone = this.cloneType diff --git a/src/test/scala/chiselTests/ComplexAssign.scala b/src/test/scala/chiselTests/ComplexAssign.scala index 0a1f31cc..c5a23f82 100644 --- a/src/test/scala/chiselTests/ComplexAssign.scala +++ b/src/test/scala/chiselTests/ComplexAssign.scala @@ -11,7 +11,7 @@ import chisel3.util._ class Complex[T <: Data](val re: T, val im: T) extends Bundle { override def cloneType: this.type = - new Complex(re.chiselCloneType, im.chiselCloneType).asInstanceOf[this.type] + new Complex(re.cloneType, im.cloneType).asInstanceOf[this.type] } class ComplexAssign(w: Int) extends Module { -- cgit v1.2.3 From 210bc8ce1cc80f7232a07c5ac8de120e5df300e7 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 11:29:59 -0700 Subject: Remove EnqIO, DeqIO - #308 --- src/main/scala/chisel3/compatibility.scala | 19 ------------------- src/main/scala/chisel3/package.scala | 22 ---------------------- 2 files changed, 41 deletions(-) diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index d13fcb06..d0d2ddb4 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -158,25 +158,6 @@ package object Chisel { // scalastyle:ignore package.object.name type DecoupledIO[+T <: Data] = chisel3.util.DecoupledIO[T] val DecoupledIO = chisel3.util.Decoupled val Decoupled = chisel3.util.Decoupled - class EnqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - def init(): Unit = { - this.noenq() - } - override def cloneType: this.type = EnqIO(gen).asInstanceOf[this.type] - } - class DeqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - chisel3.core.Binding.bind(this, chisel3.core.FlippedBinder, "Error: Cannot flip ") - def init(): Unit = { - this.nodeq() - } - override def cloneType: this.type = DeqIO(gen).asInstanceOf[this.type] - } - object EnqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen) - } - object DeqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen)) - } type QueueIO[T <: Data] = chisel3.util.QueueIO[T] type Queue[T <: Data] = chisel3.util.Queue[T] val Queue = chisel3.util.Queue diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 17ddd55a..0a57b7de 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -166,28 +166,6 @@ package object chisel3 { // scalastyle:ignore package.object.name val NODIR = chisel3.core.Direction.Unspecified type ChiselException = chisel3.internal.ChiselException - class EnqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - def init(): Unit = { - this.noenq() - } - override def cloneType: this.type = EnqIO(gen).asInstanceOf[this.type] - } - class DeqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - val Data = chisel3.core.Data - Data.setFirrtlDirection(this, Data.getFirrtlDirection(this).flip) - Binding.bind(this, FlippedBinder, "Error: Cannot flip ") - def init(): Unit = { - this.nodeq() - } - override def cloneType: this.type = DeqIO(gen).asInstanceOf[this.type] - } - object EnqIO { - def apply[T<:Data](gen: T): EnqIO[T] = new EnqIO(gen) - } - object DeqIO { - def apply[T<:Data](gen: T): DeqIO[T] = new DeqIO(gen) - } - // Debugger/Tester access to internal Chisel data structures and methods. def getDataElements(a: Aggregate): Seq[Element] = { a.allElements -- cgit v1.2.3 From 39e3d05dfcd05bb278e08543be3bbc9204e690ca Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 13:30:31 -0700 Subject: Remove non-standard sbt-buildinfo settings; write buildinfo to firrtl file. --- build.sbt | 14 +------------- src/main/scala/chisel3/Driver.scala | 1 - src/main/scala/chisel3/internal/firrtl/Emitter.scala | 2 +- src/test/scala/chiselTests/BuildInfoTests.scala | 13 ------------- 4 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 src/test/scala/chiselTests/BuildInfoTests.scala diff --git a/build.sbt b/build.sbt index f4aae4aa..09bf75ba 100644 --- a/build.sbt +++ b/build.sbt @@ -106,19 +106,7 @@ lazy val chisel = (project in file(".")). // We should really be using name.value, but currently, the package is "Chisel" (uppercase first letter) buildInfoPackage := /* name.value */ "chisel3", buildInfoOptions += BuildInfoOption.BuildTime, - buildInfoKeys := Seq[BuildInfoKey](buildInfoPackage, version, scalaVersion, sbtVersion), - // Move the managed source directory where git won't complain about it, - // and where we can easily package its files as part of the source jar artifact. - // We'd like to use versionToArray(), slice(), and mkString() to convert an explicit - // Scala version (like 2.10.6), into the leftmost two components (2.10), - // but this seems to run afoul of assumptions sbt makes about the inclusion - // of Scala-version-specfic code (we get - // BuildInfo is already defined as case class BuildInfo - // so use the full version spec. - //sourceManaged in Compile <<= (sourceDirectory in Compile, scalaVersion){ (s,v) => s / ("scala-" + versionToArray(v).slice(0,2).mkString(".") + "/src_managed") }, - sourceManaged in Compile <<= (sourceDirectory in Compile, scalaVersion){ (s,v) => s / ("scala-" + v + "/src_managed") }, - // Add the generated sources to the packagedSrc artifact since they are excluded by default. - mappings in (Compile, packageSrc) += { ((sourceManaged in Compile).value / "sbt-buildinfo" / "BuildInfo.scala") -> "BuildInfo.scala" } + buildInfoKeys := Seq[BuildInfoKey](buildInfoPackage, version, scalaVersion, sbtVersion) ). settings(commonSettings: _*). settings(customUnidocSettings: _*). diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 03f8547e..b0c7aeda 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -139,5 +139,4 @@ object Driver extends BackendCompilationUtilities { val version = BuildInfo.version val chiselVersionString = BuildInfo.toString - println(chiselVersionString) } diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index f1908089..a559ddc5 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -102,7 +102,7 @@ private class Emitter(circuit: Circuit) { private def unindent() { require(indentLevel > 0); indentLevel -= 1 } private def withIndent(f: => Unit) { indent(); f; unindent() } - private val res = new StringBuilder(s"circuit ${circuit.name} : ") + private val res = new StringBuilder(s";${Driver.chiselVersionString}\ncircuit ${circuit.name} : ") withIndent { circuit.components.foreach(c => res ++= emit(c)) } res ++= newline } diff --git a/src/test/scala/chiselTests/BuildInfoTests.scala b/src/test/scala/chiselTests/BuildInfoTests.scala deleted file mode 100644 index 21eae17c..00000000 --- a/src/test/scala/chiselTests/BuildInfoTests.scala +++ /dev/null @@ -1,13 +0,0 @@ -package chiselTests - -import org.scalatest.FlatSpec - -//import Chisel._ - -class BuildInfoTests extends FlatSpec { - behavior of "BuildInfoTests" - - it should "provide correct BuildInfo" in { - println(Chisel.Driver.chiselVersionString) - } -} -- cgit v1.2.3 From 5b8c8fbb169c9e0635bbd7274232390049e7c894 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 16:42:10 -0700 Subject: Breakup the initial emitted string per @ducky64. --- src/main/scala/chisel3/internal/firrtl/Emitter.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index a559ddc5..9c766ec3 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -102,7 +102,9 @@ private class Emitter(circuit: Circuit) { private def unindent() { require(indentLevel > 0); indentLevel -= 1 } private def withIndent(f: => Unit) { indent(); f; unindent() } - private val res = new StringBuilder(s";${Driver.chiselVersionString}\ncircuit ${circuit.name} : ") + private val res = new StringBuilder() + res ++= s";${Driver.chiselVersionString}\n" + res ++= "circuit ${circuit.name} : " withIndent { circuit.components.foreach(c => res ++= emit(c)) } res ++= newline } -- cgit v1.2.3 From 10f170110cd00e7e5e0b428c0490594dac4db225 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 16:46:27 -0700 Subject: Revert "Merge pull request #322 from ucb-bar/deleteEnqIODeqIO" This reverts commit 3ea7faaad0c3e349c531fabc8a75440337bdc235, reversing changes made to 7aea39d4deac62d5477904f4bf4381c3482c41d0. Update chisel-testers before commiting this change (deleting EnqIO/DeqIO). --- src/main/scala/chisel3/compatibility.scala | 19 +++++++++++++++++++ src/main/scala/chisel3/package.scala | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index d0d2ddb4..d13fcb06 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -158,6 +158,25 @@ package object Chisel { // scalastyle:ignore package.object.name type DecoupledIO[+T <: Data] = chisel3.util.DecoupledIO[T] val DecoupledIO = chisel3.util.Decoupled val Decoupled = chisel3.util.Decoupled + class EnqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { + def init(): Unit = { + this.noenq() + } + override def cloneType: this.type = EnqIO(gen).asInstanceOf[this.type] + } + class DeqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { + chisel3.core.Binding.bind(this, chisel3.core.FlippedBinder, "Error: Cannot flip ") + def init(): Unit = { + this.nodeq() + } + override def cloneType: this.type = DeqIO(gen).asInstanceOf[this.type] + } + object EnqIO { + def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen) + } + object DeqIO { + def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen)) + } type QueueIO[T <: Data] = chisel3.util.QueueIO[T] type Queue[T <: Data] = chisel3.util.Queue[T] val Queue = chisel3.util.Queue diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 0a57b7de..17ddd55a 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -166,6 +166,28 @@ package object chisel3 { // scalastyle:ignore package.object.name val NODIR = chisel3.core.Direction.Unspecified type ChiselException = chisel3.internal.ChiselException + class EnqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { + def init(): Unit = { + this.noenq() + } + override def cloneType: this.type = EnqIO(gen).asInstanceOf[this.type] + } + class DeqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { + val Data = chisel3.core.Data + Data.setFirrtlDirection(this, Data.getFirrtlDirection(this).flip) + Binding.bind(this, FlippedBinder, "Error: Cannot flip ") + def init(): Unit = { + this.nodeq() + } + override def cloneType: this.type = DeqIO(gen).asInstanceOf[this.type] + } + object EnqIO { + def apply[T<:Data](gen: T): EnqIO[T] = new EnqIO(gen) + } + object DeqIO { + def apply[T<:Data](gen: T): DeqIO[T] = new DeqIO(gen) + } + // Debugger/Tester access to internal Chisel data structures and methods. def getDataElements(a: Aggregate): Seq[Element] = { a.allElements -- cgit v1.2.3 From b9e2a664de7cd35ab5cd176350bafed435dc10e9 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 6 Oct 2016 16:55:42 -0700 Subject: Fix typo in emitted string. --- src/main/scala/chisel3/internal/firrtl/Emitter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 9c766ec3..e0daa95c 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -104,7 +104,7 @@ private class Emitter(circuit: Circuit) { private val res = new StringBuilder() res ++= s";${Driver.chiselVersionString}\n" - res ++= "circuit ${circuit.name} : " + res ++= s"circuit ${circuit.name} : " withIndent { circuit.components.foreach(c => res ++= emit(c)) } res ++= newline } -- cgit v1.2.3 From 87606210dd0a15122ea93136a3e9b073674d779e Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 7 Oct 2016 13:25:44 -0700 Subject: Revert "Revert "Merge pull request #322 from ucb-bar/deleteEnqIODeqIO"" This reverts commit 10f170110cd00e7e5e0b428c0490594dac4db225. --- src/main/scala/chisel3/compatibility.scala | 19 ------------------- src/main/scala/chisel3/package.scala | 22 ---------------------- 2 files changed, 41 deletions(-) diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index d13fcb06..d0d2ddb4 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -158,25 +158,6 @@ package object Chisel { // scalastyle:ignore package.object.name type DecoupledIO[+T <: Data] = chisel3.util.DecoupledIO[T] val DecoupledIO = chisel3.util.Decoupled val Decoupled = chisel3.util.Decoupled - class EnqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - def init(): Unit = { - this.noenq() - } - override def cloneType: this.type = EnqIO(gen).asInstanceOf[this.type] - } - class DeqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - chisel3.core.Binding.bind(this, chisel3.core.FlippedBinder, "Error: Cannot flip ") - def init(): Unit = { - this.nodeq() - } - override def cloneType: this.type = DeqIO(gen).asInstanceOf[this.type] - } - object EnqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen) - } - object DeqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen)) - } type QueueIO[T <: Data] = chisel3.util.QueueIO[T] type Queue[T <: Data] = chisel3.util.Queue[T] val Queue = chisel3.util.Queue diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 17ddd55a..0a57b7de 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -166,28 +166,6 @@ package object chisel3 { // scalastyle:ignore package.object.name val NODIR = chisel3.core.Direction.Unspecified type ChiselException = chisel3.internal.ChiselException - class EnqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - def init(): Unit = { - this.noenq() - } - override def cloneType: this.type = EnqIO(gen).asInstanceOf[this.type] - } - class DeqIO[+T <: Data](gen: T) extends DecoupledIO(gen) { - val Data = chisel3.core.Data - Data.setFirrtlDirection(this, Data.getFirrtlDirection(this).flip) - Binding.bind(this, FlippedBinder, "Error: Cannot flip ") - def init(): Unit = { - this.nodeq() - } - override def cloneType: this.type = DeqIO(gen).asInstanceOf[this.type] - } - object EnqIO { - def apply[T<:Data](gen: T): EnqIO[T] = new EnqIO(gen) - } - object DeqIO { - def apply[T<:Data](gen: T): DeqIO[T] = new DeqIO(gen) - } - // Debugger/Tester access to internal Chisel data structures and methods. def getDataElements(a: Aggregate): Seq[Element] = { a.allElements -- cgit v1.2.3 From bd78bb4ae8f7f6efd0abc76cb7942739de6b2da1 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 11 Oct 2016 16:56:24 -0700 Subject: Bump required verilator version. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16b759c8..7b9454c3 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ This will walk you through installing Chisel and its dependencies: ``` git pull - git checkout verilator_3_880 + git checkout verilator_3_886 ``` 1. In the Verilator repository directory, build and install: -- cgit v1.2.3 From ed872df330cb7dfabdd0e0866176f8f5be8861da Mon Sep 17 00:00:00 2001 From: Scott Beamer Date: Mon, 19 Sep 2016 16:54:16 -0700 Subject: remove trailing whitespace for annotations --- src/main/scala/chisel3/internal/firrtl/Emitter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index e0daa95c..0793fd7d 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -40,7 +40,7 @@ private class Emitter(circuit: Circuit) { s"skip" } e.sourceInfo match { - case SourceLine(filename, line, col) => s"${firrtlLine} @[${filename} ${line}:${col}] " + case SourceLine(filename, line, col) => s"${firrtlLine} @[${filename} ${line}:${col}]" case _: NoSourceInfo => firrtlLine } } -- cgit v1.2.3 From 070a8d724b282d3866da530b5d99ce7646fbf00e Mon Sep 17 00:00:00 2001 From: chick Date: Thu, 29 Sep 2016 00:37:32 -0700 Subject: Implement a standardized execution scheme for chisel Provide support for chisel options Provide support for firrtl options when called as part of chisel compile provide command line support the above options via scopt provide and execution result class that can be used when chisel3 is part of some externally controlled toolchain --- build.sbt | 27 ++-- .../scala/chisel3/ChiselExecutionOptions.scala | 34 +++++ src/main/scala/chisel3/Driver.scala | 144 ++++++++++++++++++++- src/main/scala/chisel3/testers/TesterDriver.scala | 35 +++-- src/test/scala/chiselTests/DriverSpec.scala | 33 +++++ src/test/scala/chiselTests/Reg.scala | 1 + 6 files changed, 252 insertions(+), 22 deletions(-) create mode 100644 src/main/scala/chisel3/ChiselExecutionOptions.scala create mode 100644 src/test/scala/chiselTests/DriverSpec.scala diff --git a/build.sbt b/build.sbt index 09bf75ba..04dc25ed 100644 --- a/build.sbt +++ b/build.sbt @@ -21,6 +21,8 @@ lazy val commonSettings = Seq ( scalaVersion := "2.11.7" ) +val defaultVersions = Map("firrtl" -> "1.1-SNAPSHOT") + lazy val chiselSettings = Seq ( name := "chisel3", @@ -62,19 +64,24 @@ lazy val chiselSettings = Seq ( Resolver.sonatypeRepo("releases") ), - /* Bumping "com.novocode" % "junit-interface" % "0.11", causes DelayTest testSeqReadBundle to fail - * in subtly disturbing ways on Linux (but not on Mac): - * - some fields in the generated .h file are re-named, - * - an additional field is added - * - the generated .cpp file has additional differences: - * - different temps in clock_lo - * - missing assignments - * - change of assignment order - * - use of "Tx" vs. "Tx.values" - */ + libraryDependencies ++= (Seq("firrtl").map { + dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }), + + +/* Bumping "com.novocode" % "junit-interface" % "0.11", causes DelayTest testSeqReadBundle to fail + * in subtly disturbing ways on Linux (but not on Mac): + * - some fields in the generated .h file are re-named, + * - an additional field is added + * - the generated .cpp file has additional differences: + * - different temps in clock_lo + * - missing assignments + * - change of assignment order + * - use of "Tx" vs. "Tx.values" + */ libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.5" % "test", libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.4" % "test", + libraryDependencies += "com.github.scopt" %% "scopt" % "3.4.0", // Tests from other projects may still run concurrently. parallelExecution in Test := true, diff --git a/src/main/scala/chisel3/ChiselExecutionOptions.scala b/src/main/scala/chisel3/ChiselExecutionOptions.scala new file mode 100644 index 00000000..6f58153f --- /dev/null +++ b/src/main/scala/chisel3/ChiselExecutionOptions.scala @@ -0,0 +1,34 @@ +// See LICENSE for license details. + +package chisel3 + +import firrtl.{ExecutionOptionsManager, ComposableOptions} + +//TODO: provide support for running firrtl as separate process, could alternatively be controlled by external driver +//TODO: provide option for not saving chirrtl file, instead calling firrtl with in memory chirrtl +/** + * Options that are specific to chisel. + * + * @param runFirrtlCompiler when true just run chisel, when false run chisel then compile its output with firrtl + * @note this extends FirrtlExecutionOptions which extends CommonOptions providing easy access to down chain options + */ +case class ChiselExecutionOptions( + runFirrtlCompiler: Boolean = true + // var runFirrtlAsProcess: Boolean = false + ) extends ComposableOptions + +trait HasChiselExecutionOptions { + self: ExecutionOptionsManager => + + var chiselOptions = ChiselExecutionOptions() + + parser.note("chisel3 options") + + parser.opt[Unit]("no-run-firrtl") + .abbr("chnrf") + .foreach { _ => + chiselOptions = chiselOptions.copy(runFirrtlCompiler = false) + } + .text("Stop after chisel emits chirrtl file") +} + diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index b0c7aeda..dbd9b464 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -2,11 +2,36 @@ package chisel3 +import chisel3.internal.firrtl.Emitter + import scala.sys.process._ import java.io._ -import internal._ import internal.firrtl._ +import firrtl._ + +/** + * The Driver provides methods to invoke the chisel3 compiler and the firrtl compiler. + * 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") + * with FirrtlExecutionOptions + * with ChiselExecutionOptions { + * commonOptions = CommonOption(targetDirName = "my_target_dir") + * chiselOptions = ChiselExecutionOptions(runFirrtlCompiler = false) + * } + * chisel3.Driver.execute(optionsManager, () => new Dut) + * }}} + * or via command line arguments + * @example {{{ + * args = "--no-run-firrtl --target-dir my-target-dir".split(" +") + * chisel3.execute(args, () => new DUT) + * }}} + */ import BuildInfo._ trait BackendCompilationUtilities { @@ -32,6 +57,32 @@ trait BackendCompilationUtilities { vf } + /** + * like 'firrtlToVerilog' except it runs the process inside the same JVM + * + * @param prefix basename of the file + * @param dir directory where file lives + * @return true if compiler completed successfully + */ + def compileFirrtlToVerilog(prefix: String, dir: File): Boolean = { + val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions { + commonOptions = CommonOptions(topName = prefix, targetDirName = dir.getAbsolutePath) + firrtlOptions = FirrtlExecutionOptions(compilerName = "verilog") + } + + firrtl.Driver.execute(optionsManager) match { + case _: FirrtlExecutionSuccess => true + case _: FirrtlExecutionFailure => false + } + } + + /** + * compule chirrtl to verilog by using a separate process + * + * @param prefix basename of the file + * @param dir directory where file lives + * @return true if compiler completed successfully + */ def firrtlToVerilog(prefix: String, dir: File): ProcessBuilder = { Process( Seq("firrtl", @@ -105,6 +156,30 @@ trait BackendCompilationUtilities { } } +/** + * This family provides return values from the chisel3 and possibly firrtl compile steps + */ +trait ChiselExecutionResult + +/** + * + * @param circuitOption Optional circuit, has information like circuit name + * @param emitted The emitted Chirrrl text + * @param firrtlResultOption Optional Firrtl result, @see ucb-bar/firrtl for details + */ +case class ChiselExecutionSucccess( + circuitOption: Option[Circuit], + emitted: String, + firrtlResultOption: Option[FirrtlExecutionResult] + ) extends ChiselExecutionResult + +/** + * Getting one of these indicates failure of some sort + * + * @param message a clue perhaps will be provided in the here + */ +case class ChiselExecutionFailure(message: String) extends ChiselExecutionResult + object Driver extends BackendCompilationUtilities { /** Elaborates the Module specified in the gen function into a Circuit @@ -112,7 +187,7 @@ object Driver extends BackendCompilationUtilities { * @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 elaborate[T <: Module](gen: () => T): Circuit = internal.Builder.build(Module(gen())) def emit[T <: Module](gen: () => T): String = Emitter.emit(elaborate(gen)) @@ -137,6 +212,71 @@ object Driver extends BackendCompilationUtilities { def targetDir(): String = { target_dir getOrElse new File(".").getCanonicalPath } + /** + * Run the chisel3 compiler and possibly the firrtl compiler with options specified + * + * @param optionsManager The options specified + * @param dut The device under test + * @return An execution result with useful stuff, or failure with message + */ + def execute( + optionsManager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions, + dut: () => Module): ChiselExecutionResult = { + val circuit = elaborate(dut) + + // this little hack let's us set the topName with the circuit name if it has not been set from args + optionsManager.setTopNameIfNotSet(circuit.name) + + val firrtlOptions = optionsManager.firrtlOptions + val chiselOptions = optionsManager.chiselOptions + + // use input because firrtl will be reading this + val firrtlString = Emitter.emit(circuit) + val firrtlFileName = firrtlOptions.getInputFileName(optionsManager) + val firrtlFile = new File(firrtlFileName) + + val w = new FileWriter(firrtlFile) + w.write(firrtlString) + w.close() + + val firrtlExecutionResult = if(chiselOptions.runFirrtlCompiler) { + Some(firrtl.Driver.execute(optionsManager)) + } + else { + None + } + ChiselExecutionSucccess(Some(circuit), firrtlString, firrtlExecutionResult) + } + + /** + * Run the chisel3 compiler and possibly the firrtl compiler with options specified via an array of Strings + * + * @param args The options specified, command line style + * @param dut The device under test + * @return An execution result with useful stuff, or failure with message + */ + def execute(args: Array[String], dut: () => Module): ChiselExecutionResult = { + val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions + + optionsManager.parse(args) match { + case true => + execute(optionsManager, dut) + case _ => + ChiselExecutionFailure("could not parse results") + } + } + + /** + * This is just here as command line way to see what the options are + * It will not successfully run + * TODO: Look into dynamic class loading as way to make this main useful + * + * @param args unused args + */ + def main(args: Array[String]) { + execute(Array("--help"), null) + } + val version = BuildInfo.version val chiselVersionString = BuildInfo.toString } diff --git a/src/main/scala/chisel3/testers/TesterDriver.scala b/src/main/scala/chisel3/testers/TesterDriver.scala index 586fa780..76b9a2e9 100644 --- a/src/main/scala/chisel3/testers/TesterDriver.scala +++ b/src/main/scala/chisel3/testers/TesterDriver.scala @@ -3,15 +3,13 @@ package chisel3.testers import chisel3._ -import scala.io.Source -import scala.sys.process._ import java.io._ 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) + val in = getClass.getResourceAsStream(name) if (in == null) { throw new FileNotFoundException(s"Resource '$name'") } @@ -22,7 +20,9 @@ object TesterDriver extends BackendCompilationUtilities { /** For use with modules that should successfully be elaborated by the * frontend, and which can be turned into executables with assertions. */ - def execute(t: () => BasicTester, additionalVResources: Seq[String] = Seq()): Boolean = { + def execute(t: () => BasicTester, + additionalVResources: Seq[String] = Seq(), + runFirrtlasProcess: Boolean = false): Boolean = { // Invoke the chisel compiler to get the circuit's IR val circuit = Driver.elaborate(finishWrapper(t)) @@ -46,13 +46,28 @@ object TesterDriver extends BackendCompilationUtilities { out }) - // Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe - if ((firrtlToVerilog(target, path) #&& + if(runFirrtlasProcess) { + // Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe + if ((firrtlToVerilog(target, path) #&& verilogToCpp(target, target, path, additionalVFiles, cppHarness) #&& - cppToExe(target, path)).! == 0) { - executeExpectingSuccess(target, path) - } else { - false + cppToExe(target, path)).! == 0) { + executeExpectingSuccess(target, path) + } else { + false + } + } + else { + // Compile firrtl + if (!compileFirrtlToVerilog(target, path)) { + return false + } + // Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe + if ((verilogToCpp(target, target, path, additionalVFiles, cppHarness) #&& + cppToExe(target, path)).! == 0) { + executeExpectingSuccess(target, path) + } else { + false + } } } /** diff --git a/src/test/scala/chiselTests/DriverSpec.scala b/src/test/scala/chiselTests/DriverSpec.scala new file mode 100644 index 00000000..4f9619e3 --- /dev/null +++ b/src/test/scala/chiselTests/DriverSpec.scala @@ -0,0 +1,33 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ + +import org.scalatest.{Matchers, FreeSpec} + +class DummyModule extends Module { + val io = IO(new Bundle { + val in = UInt(INPUT, 1) + val out = UInt(OUTPUT, 1) + }) + io.out := io.in +} + +class DriverSpec extends FreeSpec with Matchers { + "Driver's execute methods are used to run chisel and firrtl" - { + "options can be picked up from comand line with no args" in { + Driver.execute(Array.empty[String], () => new DummyModule) + } + "options can be picked up from comand line setting top name" in { + Driver.execute(Array("-tn", "dm", "-td", "local-build"), () => new DummyModule) + } + "execute returns a chisel execution result" in { + val args = Array("--compiler", "low") + val result = Driver.execute(Array.empty[String], () => new DummyModule) + result shouldBe a[ChiselExecutionSucccess] + val successResult = result.asInstanceOf[ChiselExecutionSucccess] + successResult.emitted should include ("circuit DummyModule") + } + } +} diff --git a/src/test/scala/chiselTests/Reg.scala b/src/test/scala/chiselTests/Reg.scala index a9086223..90992c01 100644 --- a/src/test/scala/chiselTests/Reg.scala +++ b/src/test/scala/chiselTests/Reg.scala @@ -2,6 +2,7 @@ package chiselTests +import firrtl.ir.Input import org.scalatest._ import chisel3._ import chisel3.core.DataMirror -- cgit v1.2.3 From d683e3de74e54766e8ef6f44a7dcb2e42de2df2f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 19 Oct 2016 12:57:12 -0700 Subject: Deprecate "!=". (#323) --- chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 2 ++ src/main/scala/chisel3/package.scala | 1 + src/main/scala/chisel3/util/BitPat.scala | 1 + 3 files changed, 4 insertions(+) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 741f6aee..c4161a32 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -463,6 +463,7 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None) override def do_<= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that) override def do_>= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that) + @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") final def != (that: UInt): Bool = macro SourceInfoTransform.thatArg final def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg final def === (that: UInt): Bool = macro SourceInfoTransform.thatArg @@ -658,6 +659,7 @@ sealed class SInt private (width: Width, lit: Option[SLit] = None) override def do_<= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that) override def do_>= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that) + @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") final def != (that: SInt): Bool = macro SourceInfoTransform.thatArg final def =/= (that: SInt): Bool = macro SourceInfoTransform.thatArg final def === (that: SInt): Bool = macro SourceInfoTransform.thatArg diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 0a57b7de..d0808980 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -152,6 +152,7 @@ package object chisel3 { // scalastyle:ignore package.object.name implicit class fromUIntToBitPatComparable(val x: UInt) extends AnyVal { final def === (that: BitPat): Bool = macro SourceInfoTransform.thatArg + @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") final def != (that: BitPat): Bool = macro SourceInfoTransform.thatArg final def =/= (that: BitPat): Bool = macro SourceInfoTransform.thatArg diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 972010a6..e58258c7 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -82,6 +82,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def getWidth: Int = width def === (that: UInt): Bool = macro SourceInfoTransform.thatArg def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg + @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") def != (that: UInt): Bool = macro SourceInfoTransform.thatArg def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = value.asUInt === (that & mask.asUInt) // scalastyle:ignore method.name -- cgit v1.2.3 From 5df30b390ae5817c4793c6d4e0c5466d96d241f1 Mon Sep 17 00:00:00 2001 From: jackkoenig Date: Wed, 19 Oct 2016 11:34:25 -0700 Subject: Change verilogToCpp to use O0 This causes Verilator tests to compile faster and use less memory --- src/main/scala/chisel3/Driver.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index dbd9b464..a0713379 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -119,13 +119,13 @@ trait BackendCompilationUtilities { "-Wno-WIDTH", "-Wno-STMTDLY", "--trace", - "-O2", + "-O0", "--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 -O2 -DTOP_TYPE=V$dutFile -include V$dutFile.h""", + s"""-Wno-undefined-bool-conversion -O0 -DTOP_TYPE=V$dutFile -include V$dutFile.h""", "-Mdir", dir.toString, "--exe", cppHarness.toString) System.out.println(s"${command.mkString(" ")}") // scalastyle:ignore regex -- cgit v1.2.3