summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Annotation.scala90
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala69
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Mem.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Module.scala8
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/Builder.scala19
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala4
-rw-r--r--src/main/scala/chisel3/Driver.scala22
-rw-r--r--src/main/scala/chisel3/package.scala3
-rw-r--r--src/main/scala/chisel3/util/BlackBoxUtils.scala17
-rw-r--r--src/test/scala/chiselTests/AnnotatingDiamondSpec.scala78
-rw-r--r--src/test/scala/chiselTests/AnnotationNoDedup.scala18
-rw-r--r--src/test/scala/chiselTests/ChiselSpec.scala6
-rw-r--r--src/test/scala/chiselTests/DriverSpec.scala4
14 files changed, 199 insertions, 143 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala b/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala
new file mode 100644
index 00000000..cfee67cb
--- /dev/null
+++ b/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala
@@ -0,0 +1,90 @@
+// See LICENSE for license details.
+
+package chisel3.core
+
+import scala.language.existentials
+
+import chisel3.internal.{Builder, InstanceId}
+import firrtl.Transform
+import firrtl.annotations.{Annotation, CircuitName, ComponentName, ModuleName}
+import firrtl.transforms.DontTouchAnnotation
+
+/** Interface for Annotations in Chisel
+ *
+ * Defines a conversion to a corresponding FIRRTL Annotation
+ */
+trait ChiselAnnotation {
+ /** Conversion to FIRRTL Annotation */
+ def toFirrtl: Annotation
+}
+object ChiselAnnotation {
+ @deprecated("Write a custom ChiselAnnotation subclass instead", "3.1")
+ def apply(component: InstanceId, transformClass: Class[_ <: Transform], value: String) =
+ ChiselLegacyAnnotation(component, transformClass, value)
+ @deprecated("Write a custom ChiselAnnotation subclass instead", "3.1")
+ def unapply(anno: ChiselAnnotation): Option[(InstanceId, Class[_ <: Transform], String)] =
+ anno match {
+ case ChiselLegacyAnnotation(c, t, v) => Some(c, t, v)
+ case _ => None
+ }
+}
+
+/** Mixin for [[ChiselAnnotation]] that instantiates an associated FIRRTL Transform when this
+ * Annotation is present during a run of [[chisel3.Driver.execute]]. Automatic Transform
+ * instantiation is *not* supported when the Circuit and Annotations are serialized before invoking
+ * FIRRTL.
+ */
+// TODO There should be a FIRRTL API for this instead
+trait RunFirrtlTransform extends ChiselAnnotation {
+ def transformClass: Class[_ <: Transform]
+}
+
+// This exists for implementation reasons, we don't want people using this type directly
+final case class ChiselLegacyAnnotation private[chisel3] (
+ component: InstanceId,
+ transformClass: Class[_ <: Transform],
+ value: String) extends ChiselAnnotation with RunFirrtlTransform {
+ def toFirrtl: Annotation = Annotation(component.toNamed, transformClass, value)
+}
+private[chisel3] object ChiselLegacyAnnotation
+
+object annotate { // scalastyle:ignore object.name
+ def apply(anno: ChiselAnnotation): Unit = {
+ Builder.annotations += anno
+ }
+}
+
+/** Marks that a signal should not be removed by Chisel and Firrtl optimization passes
+ *
+ * @example {{{
+ * class MyModule extends Module {
+ * val io = IO(new Bundle {
+ * val a = Input(UInt(32.W))
+ * val b = Output(UInt(32.W))
+ * })
+ * io.b := io.a
+ * val dead = io.a +% 1.U // normally dead would be pruned by DCE
+ * dontTouch(dead) // Marking it as such will preserve it
+ * }
+ * }}}
+ *
+ * @note Calling this on [[Data]] creates an annotation that Chisel emits to a separate annotations
+ * file. This file must be passed to FIRRTL independently of the `.fir` file. The execute methods
+ * in [[chisel3.Driver]] will pass the annotations to FIRRTL automatically.
+ */
+object dontTouch { // scalastyle:ignore object.name
+ /** Marks a signal to be preserved in Chisel and Firrtl
+ *
+ * @note Requires the argument to be bound to hardware
+ * @param data The signal to be marked
+ * @return Unmodified signal `data`
+ */
+ def apply[T <: Data](data: T)(implicit compileOptions: CompileOptions): T = {
+ if (compileOptions.checkSynthesizable) {
+ requireIsHardware(data, "Data marked dontTouch")
+ }
+ annotate(new ChiselAnnotation { def toFirrtl = DontTouchAnnotation(data.toNamed) })
+ data
+ }
+}
+
diff --git a/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala b/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala
deleted file mode 100644
index 98253ce5..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.existentials
-
-import chisel3.internal.{Builder, InstanceId}
-import firrtl.Transform
-import firrtl.annotations.{Annotation, CircuitName, ComponentName, ModuleName}
-
-/**
- * This is a stand-in for the firrtl.Annotations.Annotation because at the time this annotation
- * is created the component cannot be resolved, into a targetString. Resolution can only
- * happen after the circuit is elaborated
- * @param component A chisel thingy to be annotated, could be module, wire, reg, etc.
- * @param transformClass A fully-qualified class name of the transformation pass
- * @param value A string value to be used by the transformation pass
- */
-case class ChiselAnnotation(component: InstanceId, transformClass: Class[_ <: Transform], value: String) {
- def toFirrtl: Annotation = {
- val circuitName = CircuitName(component.pathName.split("""\.""").head)
- component match {
- case m: BaseModule =>
- Annotation(
- ModuleName(m.name, circuitName), transformClass, value)
- case _ =>
- Annotation(
- ComponentName(
- component.instanceName, ModuleName(component.parentModName, circuitName)), transformClass, value)
- }
- }
-}
-
-/** Marks that a signal should not be removed by Chisel and Firrtl optimization passes
- *
- * @example {{{
- * class MyModule extends Module {
- * val io = IO(new Bundle {
- * val a = Input(UInt(32.W))
- * val b = Output(UInt(32.W))
- * })
- * io.b := io.a
- * val dead = io.a +% 1.U // normally dead would be pruned by DCE
- * dontTouch(dead) // Marking it as such will preserve it
- * }
- * }}}
- *
- * @note Calling this on [[Data]] creates an annotation that Chisel emits to a separate annotations
- * file. This file must be passed to FIRRTL independently of the `.fir` file. The execute methods
- * in [[chisel3.Driver]] will pass the annotations to FIRRTL automatically.
- */
-object dontTouch { // scalastyle:ignore object.name
- /** Marks a signal to be preserved in Chisel and Firrtl
- *
- * @note Requires the argument to be bound to hardware
- * @param data The signal to be marked
- * @return Unmodified signal `data`
- */
- def apply[T <: Data](data: T)(implicit compileOptions: CompileOptions): T = {
- if (compileOptions.checkSynthesizable) {
- requireIsHardware(data, "Data marked dontTouch")
- }
- // TODO unify with firrtl.transforms.DontTouchAnnotation
- val anno = ChiselAnnotation(data, classOf[firrtl.Transform], "DONTtouch!")
- Builder.annotations += anno
- data
- }
-}
-
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index 40781490..65f89cc1 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -198,7 +198,7 @@ object Flipped {
* time) of bits, and must have methods to pack / unpack structured data to /
* from bits.
*/
-abstract class Data extends HasId {
+abstract class Data extends HasId with NamedComponent {
// This is a bad API that punches through object boundaries.
@deprecated("pending removal once all instances replaced", "chisel3")
private[chisel3] def flatten: IndexedSeq[Element] = {
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
index c9208030..3fe78010 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
@@ -31,7 +31,7 @@ object Mem {
}
}
-sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId {
+sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId with NamedComponent {
// REVIEW TODO: make accessors (static/dynamic, read/write) combinations consistent.
/** Creates a read accessor into the memory with static addressing. See the
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
index 5ba6dbc8..5a4f6abb 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
@@ -13,6 +13,8 @@ import chisel3.internal.Builder._
import chisel3.internal.firrtl._
import chisel3.internal.sourceinfo.{InstTransform, SourceInfo}
+import _root_.firrtl.annotations.{CircuitName, ModuleName}
+
object Module {
/** A wrapper method that all Module instantiations must be wrapped in
* (necessary to help Chisel track internal state).
@@ -139,6 +141,11 @@ abstract class BaseModule extends HasId {
/** Legalized name of this module. */
final val name = Builder.globalNamespace.name(desiredName)
+ /** Returns a FIRRTL ModuleName that references this object
+ * @note Should not be called until circuit elaboration is complete
+ */
+ final def toNamed: ModuleName = ModuleName(this.name, CircuitName(this.circuitName))
+
/** Called at the Module.apply(...) level after this Module has finished elaborating.
* Returns a map of nodes -> names, for named nodes.
*
@@ -196,6 +203,7 @@ abstract class BaseModule extends HasId {
//
// BaseModule User API functions
//
+ @deprecated("Use chisel3.experimental.annotate instead", "3.1")
protected def annotate(annotation: ChiselAnnotation): Unit = {
Builder.annotations += annotation
}
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
index 5c5c690e..2cb206d4 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
@@ -8,6 +8,7 @@ import scala.collection.mutable.{ArrayBuffer, HashMap}
import chisel3._
import core._
import firrtl._
+import _root_.firrtl.annotations.{CircuitName, ComponentName, ModuleName, Named}
private[chisel3] class Namespace(keywords: Set[String]) {
private val names = collection.mutable.HashMap[String, Long]()
@@ -66,6 +67,9 @@ trait InstanceId {
def pathName: String
def parentPathName: String
def parentModName: String
+ /** Returns a FIRRTL Named that refers to this object in the elaborated hardware graph */
+ def toNamed: Named
+
}
private[chisel3] trait HasId extends InstanceId {
@@ -129,6 +133,11 @@ private[chisel3] trait HasId extends InstanceId {
case Some(p) => p.name
case None => throwException(s"$instanceName doesn't have a parent")
}
+ // TODO Should this be public?
+ protected def circuitName: String = _parent match {
+ case None => instanceName
+ case Some(p) => p.circuitName
+ }
private[chisel3] def getPublicFields(rootClass: Class[_]): Seq[java.lang.reflect.Method] = {
// Suggest names to nodes using runtime reflection
@@ -142,6 +151,14 @@ private[chisel3] trait HasId extends InstanceId {
this.getClass.getMethods.sortWith(_.getName < _.getName).filter(isPublicVal(_))
}
}
+/** Holds the implementation of toNamed for Data and MemBase */
+private[chisel3] trait NamedComponent extends HasId {
+ /** Returns a FIRRTL ComponentName that references this object
+ * @note Should not be called until circuit elaboration is complete
+ */
+ final def toNamed: ComponentName =
+ ComponentName(this.instanceName, ModuleName(this.parentModName, CircuitName(this.circuitName)))
+}
private[chisel3] class DynamicContext() {
val idGen = new IdGen
@@ -277,7 +294,7 @@ private[chisel3] object Builder {
errors.checkpoint()
errors.info("Done elaborating.")
- Circuit(components.last.name, components, annotations.map(_.toFirrtl))
+ Circuit(components.last.name, components, annotations)
}
}
initializeSingletons()
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
index b499c2b1..6b555a82 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -7,8 +7,6 @@ import core._
import chisel3.internal._
import chisel3.internal.sourceinfo.{SourceInfo, NoSourceInfo}
-import _root_.firrtl.annotations.Annotation
-
case class PrimOp(val name: String) {
override def toString: String = name
}
@@ -278,4 +276,4 @@ abstract class Component extends Arg {
case class DefModule(id: UserModule, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component
case class DefBlackBox(id: BaseBlackBox, name: String, ports: Seq[Port], topDir: SpecifiedDirection, params: Map[String, Param]) extends Component
-case class Circuit(name: String, components: Seq[Component], annotations: Seq[Annotation] = Seq.empty)
+case class Circuit(name: String, components: Seq[Component], annotations: Seq[ChiselAnnotation] = Seq.empty)
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala
index dae921ab..25d25425 100644
--- a/src/main/scala/chisel3/Driver.scala
+++ b/src/main/scala/chisel3/Driver.scala
@@ -3,13 +3,14 @@
package chisel3
import chisel3.internal.firrtl.Emitter
-import chisel3.experimental.RawModule
+import chisel3.experimental.{RawModule, RunFirrtlTransform}
import java.io._
import net.jcazevedo.moultingyaml._
import internal.firrtl._
import firrtl._
+import firrtl.annotations.{Annotation, JsonProtocol}
import firrtl.util.{ BackendCompilationUtilities => FirrtlBackendCompilationUtilities }
import _root_.firrtl.annotations.AnnotationYamlProtocol._
@@ -153,9 +154,10 @@ object Driver extends BackendCompilationUtilities {
w.write(firrtlString)
w.close()
- val annotationFile = new File(optionsManager.getBuildFileName("anno"))
+ val annotationFile = new File(optionsManager.getBuildFileName("anno.json"))
val af = new FileWriter(annotationFile)
- af.write(circuit.annotations.toArray.toYaml.prettyPrint)
+ val firrtlAnnos = circuit.annotations.map(_.toFirrtl)
+ af.write(JsonProtocol.serialize(firrtlAnnos))
af.close()
/** Find the set of transform classes associated with annotations then
@@ -164,16 +166,16 @@ object Driver extends BackendCompilationUtilities {
* transform being instantiated
*/
val transforms = circuit.annotations
- .map(_.transform)
- .distinct
- .filterNot(_ == classOf[firrtl.Transform])
- .map { transformClass: Class[_ <: Transform] =>
- transformClass.newInstance()
- }
+ .collect { case anno: RunFirrtlTransform => anno.transformClass }
+ .distinct
+ .filterNot(_ == classOf[firrtl.Transform])
+ .map { transformClass: Class[_ <: Transform] =>
+ transformClass.newInstance()
+ }
/* This passes the firrtl source and annotations directly to firrtl */
optionsManager.firrtlOptions = optionsManager.firrtlOptions.copy(
firrtlSource = Some(firrtlString),
- annotations = optionsManager.firrtlOptions.annotations ++ circuit.annotations.toList,
+ annotations = optionsManager.firrtlOptions.annotations ++ firrtlAnnos,
customTransforms = optionsManager.firrtlOptions.customTransforms ++ transforms.toList)
val firrtlExecutionResult = if(chiselOptions.runFirrtlCompiler) {
diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala
index 973ad026..b3a9f54b 100644
--- a/src/main/scala/chisel3/package.scala
+++ b/src/main/scala/chisel3/package.scala
@@ -439,6 +439,9 @@ package object chisel3 { // scalastyle:ignore package.object.name
type ChiselAnnotation = chisel3.core.ChiselAnnotation
val ChiselAnnotation = chisel3.core.ChiselAnnotation
+ type RunFirrtlTransform = chisel3.core.RunFirrtlTransform
+
+ val annotate = chisel3.core.annotate
val DataMirror = chisel3.core.DataMirror
val requireIsHardware = chisel3.core.requireIsHardware
diff --git a/src/main/scala/chisel3/util/BlackBoxUtils.scala b/src/main/scala/chisel3/util/BlackBoxUtils.scala
index fbcf4a59..fa62184a 100644
--- a/src/main/scala/chisel3/util/BlackBoxUtils.scala
+++ b/src/main/scala/chisel3/util/BlackBoxUtils.scala
@@ -3,14 +3,18 @@
package chisel3.util
import chisel3._
-import chisel3.core.ChiselAnnotation
-import firrtl.transforms.{BlackBoxInline, BlackBoxResource, BlackBoxSourceHelper}
+import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform}
+import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxInlineAnno, BlackBoxSourceHelper}
trait HasBlackBoxResource extends BlackBox {
self: BlackBox =>
def setResource(blackBoxResource: String): Unit = {
- annotate(ChiselAnnotation(self, classOf[BlackBoxSourceHelper], BlackBoxResource(blackBoxResource).serialize))
+ val anno = new ChiselAnnotation with RunFirrtlTransform {
+ def toFirrtl = BlackBoxResourceAnno(self.toNamed, blackBoxResource)
+ def transformClass = classOf[BlackBoxSourceHelper]
+ }
+ chisel3.experimental.annotate(anno)
}
}
@@ -18,7 +22,10 @@ trait HasBlackBoxInline extends BlackBox {
self: BlackBox =>
def setInline(blackBoxName: String, blackBoxInline: String): Unit = {
- annotate(ChiselAnnotation(
- self, classOf[BlackBoxSourceHelper], BlackBoxInline(blackBoxName, blackBoxInline).serialize))
+ val anno = new ChiselAnnotation with RunFirrtlTransform {
+ def toFirrtl = BlackBoxInlineAnno(self.toNamed, blackBoxName, blackBoxInline)
+ def transformClass = classOf[BlackBoxSourceHelper]
+ }
+ chisel3.experimental.annotate(anno)
}
}
diff --git a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala
index f792c56f..e88d475e 100644
--- a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala
+++ b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala
@@ -3,47 +3,50 @@
package chiselTests
import chisel3._
-import chisel3.experimental.ChiselAnnotation
+import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform}
import chisel3.internal.InstanceId
import chisel3.testers.BasicTester
-import firrtl.{CircuitForm, CircuitState, LowForm, Transform}
-import firrtl.annotations.{Annotation, ModuleName, Named}
+import firrtl.{CircuitState, LowForm, Transform}
+import firrtl.annotations.{
+ Annotation,
+ SingleTargetAnnotation,
+ ModuleName,
+ Named
+}
import org.scalatest._
-//scalastyle:off magic.number
-/**
- * This and the Identity transform class are a highly schematic implementation of a
- * library implementation of (i.e. code outside of firrtl itself)
+/** These annotations and the IdentityTransform class serve as an example of how to write a
+ * Chisel/Firrtl library
*/
-object IdentityAnnotation {
- def apply(target: Named, value: String): Annotation = Annotation(target, classOf[IdentityTransform], value)
-
- def unapply(a: Annotation): Option[(Named, String)] = a match {
- case Annotation(named, t, value) if t == classOf[IdentityTransform] => Some((named, value))
- case _ => None
+case class IdentityAnnotation(target: Named, value: String) extends SingleTargetAnnotation[Named] {
+ def duplicate(n: Named) = this.copy(target = n)
+}
+/** ChiselAnnotation that corresponds to the above FIRRTL annotation */
+case class IdentityChiselAnnotation(target: InstanceId, value: String)
+ extends ChiselAnnotation with RunFirrtlTransform {
+ def toFirrtl = IdentityAnnotation(target.toNamed, value)
+ def transformClass = classOf[IdentityTransform]
+}
+object identify {
+ def apply(component: InstanceId, value: String): Unit = {
+ val anno = IdentityChiselAnnotation(component, value)
+ annotate(anno)
}
}
class IdentityTransform extends Transform {
- override def inputForm: CircuitForm = LowForm
+ def inputForm = LowForm
+ def outputForm = LowForm
- override def outputForm: CircuitForm = LowForm
-
- override def execute(state: CircuitState): CircuitState = {
- getMyAnnotations(state) match {
- case Nil => state
- case myAnnotations =>
- state
+ def execute(state: CircuitState): CircuitState = {
+ val annosx = state.annotations.map {
+ case IdentityAnnotation(t, value) => IdentityAnnotation(t, value + ":seen")
+ case other => other
}
+ state.copy(annotations = annosx)
}
}
-trait IdentityAnnotator {
- self: Module =>
- def identify(component: InstanceId, value: String): Unit = {
- annotate(ChiselAnnotation(component, classOf[IdentityTransform], value))
- }
-}
/** A diamond circuit Top instantiates A and B and both A and B instantiate C
* Illustrations of annotations of various components and modules in both
* relative and absolute cases
@@ -54,7 +57,7 @@ trait IdentityAnnotator {
* This class has parameterizable widths, it will generate different hardware
* @param widthC io width
*/
-class ModC(widthC: Int) extends Module with IdentityAnnotator {
+class ModC(widthC: Int) extends Module {
val io = IO(new Bundle {
val in = Input(UInt(widthC.W))
val out = Output(UInt(widthC.W))
@@ -71,7 +74,7 @@ class ModC(widthC: Int) extends Module with IdentityAnnotator {
* based on it's parameter
* @param annoParam parameter is only used in annotation not in circuit
*/
-class ModA(annoParam: Int) extends Module with IdentityAnnotator {
+class ModA(annoParam: Int) extends Module {
val io = IO(new Bundle {
val in = Input(UInt())
val out = Output(UInt())
@@ -86,7 +89,7 @@ class ModA(annoParam: Int) extends Module with IdentityAnnotator {
identify(io.out, s"ModA.io.out(ignore_param)")
}
-class ModB(widthB: Int) extends Module with IdentityAnnotator{
+class ModB(widthB: Int) extends Module {
val io = IO(new Bundle {
val in = Input(UInt(widthB.W))
val out = Output(UInt(widthB.W))
@@ -98,7 +101,7 @@ class ModB(widthB: Int) extends Module with IdentityAnnotator{
identify(io.in, s"modB.io.in annotated from inside modB")
}
-class TopOfDiamond extends Module with IdentityAnnotator {
+class TopOfDiamond extends Module {
val io = IO(new Bundle {
val in = Input(UInt(32.W))
val out = Output(UInt(32.W))
@@ -128,9 +131,6 @@ class DiamondTester extends BasicTester {
}
class AnnotatingDiamondSpec extends FreeSpec with Matchers {
- def findAnno(as: Seq[Annotation], name: String): Option[Annotation] = {
- as.find { a => a.targetString == name }
- }
"""
|Diamond is an example of a module that has two sub-modules A and B who both instantiate their
@@ -144,16 +144,16 @@ class AnnotatingDiamondSpec extends FreeSpec with Matchers {
Driver.execute(Array("--target-dir", "test_run_dir"), () => new TopOfDiamond) match {
case ChiselExecutionSuccess(Some(circuit), emitted, _) =>
- val annos = circuit.annotations
- annos.length should be (10)
+ val annos = circuit.annotations.map(_.toFirrtl)
+ annos.count(_.isInstanceOf[IdentityAnnotation]) should be (10)
annos.count {
- case Annotation(ModuleName(name, _), _, annoValue) => name == "ModC" && annoValue == "ModC(16)"
+ case IdentityAnnotation(ModuleName("ModC", _), "ModC(16)") => true
case _ => false
} should be (1)
annos.count {
- case Annotation(ModuleName(name, _), _, annoValue) => name == "ModC_1" && annoValue == "ModC(32)"
+ case IdentityAnnotation(ModuleName("ModC_1", _), "ModC(32)") => true
case _ => false
} should be (1)
case _ =>
@@ -161,4 +161,4 @@ class AnnotatingDiamondSpec extends FreeSpec with Matchers {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/test/scala/chiselTests/AnnotationNoDedup.scala b/src/test/scala/chiselTests/AnnotationNoDedup.scala
index 93167f69..d93da31f 100644
--- a/src/test/scala/chiselTests/AnnotationNoDedup.scala
+++ b/src/test/scala/chiselTests/AnnotationNoDedup.scala
@@ -3,16 +3,14 @@
package chiselTests
import chisel3._
-import chisel3.experimental.ChiselAnnotation
+import chisel3.experimental.{annotate, ChiselAnnotation}
import firrtl.FirrtlExecutionSuccess
-import firrtl.transforms.DedupModules
+import firrtl.transforms.NoDedupAnnotation
import org.scalatest.{FreeSpec, Matchers}
-trait NoDedupAnnotator {
- self: Module =>
-
- def doNotDedup(module: Module): Unit = {
- annotate(ChiselAnnotation(module, classOf[DedupModules], "nodedup!"))
+object doNotDedup {
+ def apply(module: Module): Unit = {
+ annotate(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(module.toNamed) })
}
}
@@ -24,7 +22,7 @@ class MuchUsedModule extends Module {
io.out := io.in +% 1.U
}
-class UsesMuchUsedModule(addAnnos: Boolean) extends Module with NoDedupAnnotator{
+class UsesMuchUsedModule(addAnnos: Boolean) extends Module {
val io = IO(new Bundle {
val in = Input(UInt(16.W))
val out = Output(UInt(16.W))
@@ -49,7 +47,7 @@ class UsesMuchUsedModule(addAnnos: Boolean) extends Module with NoDedupAnnotator
class AnnotationNoDedup extends FreeSpec with Matchers {
"Firrtl provides transform that reduces identical modules to a single instance" - {
- "Annotations can be added which will defeat this deduplication for specific modules instances" in {
+ "Annotations can be added which will prevent this deduplication for specific modules instances" in {
Driver.execute(Array("-X", "low", "--target-dir", "test_run_dir"), () => new UsesMuchUsedModule(addAnnos = true)) match {
case ChiselExecutionSuccess(_, _, Some(firrtlResult: FirrtlExecutionSuccess)) =>
val lowFirrtl = firrtlResult.emitted
@@ -62,7 +60,7 @@ class AnnotationNoDedup extends FreeSpec with Matchers {
case _ =>
}
}
- "Turning off these nnotations dedup all the occurrences" in {
+ "Turning off these annotations dedups all the occurrences" in {
Driver.execute(Array("-X", "low", "--target-dir", "test_run_dir"), () => new UsesMuchUsedModule(addAnnos = false)) match {
case ChiselExecutionSuccess(_, _, Some(firrtlResult: FirrtlExecutionSuccess)) =>
val lowFirrtl = firrtlResult.emitted
diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala
index 14672d68..661cf00e 100644
--- a/src/test/scala/chiselTests/ChiselSpec.scala
+++ b/src/test/scala/chiselTests/ChiselSpec.scala
@@ -16,9 +16,10 @@ import firrtl.{
FirrtlExecutionSuccess,
FirrtlExecutionFailure
}
+import firrtl.util.BackendCompilationUtilities
/** Common utility functions for Chisel unit tests. */
-trait ChiselRunners extends Assertions {
+trait ChiselRunners extends Assertions with BackendCompilationUtilities {
def runTester(t: => BasicTester, additionalVResources: Seq[String] = Seq()): Boolean = {
TesterDriver.execute(() => t, additionalVResources)
}
@@ -43,9 +44,10 @@ trait ChiselRunners extends Assertions {
* @return the Verilog code as a string.
*/
def compile(t: => RawModule): String = {
+ val testDir = createTestDirectory(this.getClass.getSimpleName)
val manager = new ExecutionOptionsManager("compile") with HasFirrtlOptions
with HasChiselExecutionOptions {
- commonOptions = CommonOptions(targetDirName = "test_run_dir")
+ commonOptions = CommonOptions(targetDirName = testDir.toString)
}
Driver.execute(manager, () => t) match {
diff --git a/src/test/scala/chiselTests/DriverSpec.scala b/src/test/scala/chiselTests/DriverSpec.scala
index 796668e3..612bdef2 100644
--- a/src/test/scala/chiselTests/DriverSpec.scala
+++ b/src/test/scala/chiselTests/DriverSpec.scala
@@ -25,7 +25,7 @@ class DriverSpec extends FreeSpec with Matchers {
val targetDir = "."
Driver.execute(Array.empty[String], () => new DummyModule) match {
case ChiselExecutionSuccess(_, _, Some(_: FirrtlExecutionSuccess)) =>
- val exts = List("anno", "fir", "v")
+ val exts = List("anno.json", "fir", "v")
for (ext <- exts) {
val dummyOutput = new File(targetDir, "DummyModule" + "." + ext)
dummyOutput.exists() should be(true)
@@ -41,7 +41,7 @@ class DriverSpec extends FreeSpec with Matchers {
val targetDir = "local-build"
Driver.execute(Array("-tn", "dm", "-td", targetDir), () => new DummyModule) match {
case ChiselExecutionSuccess(_, _, Some(_: FirrtlExecutionSuccess)) =>
- val exts = List("anno", "fir", "v")
+ val exts = List("anno.json", "fir", "v")
for (ext <- exts) {
val dummyOutput = new File(targetDir, "dm" + "." + ext)
dummyOutput.exists() should be(true)