aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Annotations.scala239
-rw-r--r--src/main/scala/firrtl/Compiler.scala10
-rw-r--r--src/main/scala/firrtl/Driver.scala38
-rw-r--r--src/main/scala/firrtl/ExecutionOptionsManager.scala29
-rw-r--r--src/main/scala/firrtl/annotations/Annotation.scala21
-rw-r--r--src/main/scala/firrtl/annotations/AnnotationUtils.scala74
-rw-r--r--src/main/scala/firrtl/annotations/AnnotationYamlProtocol.scala37
-rw-r--r--src/main/scala/firrtl/annotations/Named.scala31
-rw-r--r--src/main/scala/firrtl/passes/Inline.scala12
-rw-r--r--src/main/scala/firrtl/passes/clocklist/ClockList.scala2
-rw-r--r--src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala24
-rw-r--r--src/main/scala/firrtl/passes/clocklist/ClockListUtils.scala2
-rw-r--r--src/main/scala/firrtl/passes/clocklist/RemoveAllButClocks.scala2
-rw-r--r--src/main/scala/firrtl/passes/memlib/DecorateMems.scala2
-rw-r--r--src/main/scala/firrtl/passes/memlib/InferReadWrite.scala17
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala20
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala48
-rw-r--r--src/main/scala/firrtl/passes/wiring/Wiring.scala3
-rw-r--r--src/main/scala/firrtl/passes/wiring/WiringTransform.scala56
-rw-r--r--src/main/scala/firrtl/passes/wiring/WiringUtils.scala2
-rw-r--r--src/main/scala/firrtl/transforms/Dedup.scala8
-rw-r--r--src/test/resources/annotations/SampleAnnotations.anno30
-rw-r--r--src/test/scala/firrtlTests/AnnotationTests.scala21
-rw-r--r--src/test/scala/firrtlTests/AttachSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/CInferMDirSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/ChirrtlMemSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/ClockListTests.scala2
-rw-r--r--src/test/scala/firrtlTests/DriverSpec.scala28
-rw-r--r--src/test/scala/firrtlTests/FirrtlSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/InferReadWriteSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/InlineInstancesTests.scala7
-rw-r--r--src/test/scala/firrtlTests/MultiThreadingSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/PassTests.scala2
-rw-r--r--src/test/scala/firrtlTests/ReplSeqMemTests.scala2
-rw-r--r--src/test/scala/firrtlTests/VerilogEmitterTests.scala2
-rw-r--r--src/test/scala/firrtlTests/WiringTests.scala2
-rw-r--r--src/test/scala/firrtlTests/fixed/FixedPointMathSpec.scala3
-rw-r--r--src/test/scala/firrtlTests/fixed/RemoveFixedTypeSpec.scala1
-rw-r--r--src/test/scala/firrtlTests/transforms/DedupTests.scala9
39 files changed, 411 insertions, 387 deletions
diff --git a/src/main/scala/firrtl/Annotations.scala b/src/main/scala/firrtl/Annotations.scala
deleted file mode 100644
index b502e055..00000000
--- a/src/main/scala/firrtl/Annotations.scala
+++ /dev/null
@@ -1,239 +0,0 @@
-// See LICENSE for license details.
-
-package firrtl
-
-import firrtl.ir._
-
-import scala.collection.mutable
-import java.io.Writer
-
-
-/**
- * Firrtl Annotation Library
- *
- * WARNING(izraelevitz): Untested, and requires unit tests, which require the
- * LowerTypes pass and ConstProp pass to correctly populate its RenameMap.
- *
- * The following tables explain how Tenacity and Permissibility interact
- * with different RenameMap scenarios:
- * x -> x : a component named "x" is renamed to the same name, "x"
- * x -> y : a component named "x" is renamed to a different name, "y"
- * x -> y,z : a component named "x" is split into two components named "y" and "z"
- * x -> () : a component named "x" is removed
- *
- * Tenacity Propagation Behavior:
- * ----------|----------|----------|------------|-----------|
- * | x -> x | x -> y | x -> y,z | x -> () |
- * ----------|----------|----------|------------|-----------|
- * Unstable | x | () | () | () |
- * Fickle | x | y | () | () |
- * Insistent | x | y | y | () |
- * Sticky | x | y | y,z | () |
- * ----------|----------|----------|------------|-----------|
- *
- * Permissibility Accepted Ranges:
- * ----------|----------|----------|------------|-----------|
- * | x -> x | x -> y | x -> y,z | x -> () |
- * ----------|----------|----------|------------|-----------|
- * Strict | ok | error | error | error |
- * Rigid | ok | ok | error | error |
- * Firm | ok | ok | ok | error |
- * Loose | ok | ok | ok | ok |
- * ----------|----------|----------|------------|-----------|
- */
-object Annotations {
- /** Returns true if a valid Module name */
- val SerializedModuleName = """([a-zA-Z_][a-zA-Z_0-9~!@#$%^*\-+=?/]*)""".r
- def validModuleName(s: String): Boolean = s match {
- case SerializedModuleName(name) => true
- case _ => false
- }
-
- /** Returns true if a valid component/subcomponent name */
- val SerializedComponentName = """([a-zA-Z_][a-zA-Z_0-9\[\]\.~!@#$%^*\-+=?/]*)""".r
- def validComponentName(s: String): Boolean = s match {
- case SerializedComponentName(name) => true
- case _ => false
- }
-
- /** Tokenizes a string with '[', ']', '.' as tokens, e.g.:
- * "foo.bar[boo.far]" becomes Seq("foo" "." "bar" "[" "boo" "." "far" "]")
- */
- def tokenize(s: String): Seq[String] = s.find(c => "[].".contains(c)) match {
- case Some(_) =>
- val i = s.indexWhere(c => "[].".contains(c))
- Seq(s.slice(0, i), s(i).toString) ++ tokenize(s.drop(i + 1))
- case None => Seq(s)
- }
-
- /** Given a serialized component/subcomponent reference, subindex, subaccess,
- * or subfield, return the corresponding IR expression.
- */
- def toExp(s: String): Expression = {
- def parse(tokens: Seq[String]): Expression = {
- val DecPattern = """([1-9]\d*)""".r
- def findClose(tokens: Seq[String], index: Int, nOpen: Int): Seq[String] =
- if(index >= tokens.size) {
- error("Cannot find closing bracket ]")
- } else tokens(index) match {
- case "[" => findClose(tokens, index + 1, nOpen + 1)
- case "]" if nOpen == 1 => tokens.slice(1, index)
- case _ => findClose(tokens, index + 1, nOpen)
- }
- def buildup(e: Expression, tokens: Seq[String]): Expression = tokens match {
- case "[" :: tail =>
- val indexOrAccess = findClose(tokens, 0, 0)
- indexOrAccess.head match {
- case DecPattern(d) => SubIndex(e, d.toInt, UnknownType)
- case _ => buildup(SubAccess(e, parse(indexOrAccess), UnknownType), tokens.slice(1, indexOrAccess.size))
- }
- case "." :: tail =>
- buildup(SubField(e, tokens(1), UnknownType), tokens.drop(2))
- case Nil => e
- }
- val root = Reference(tokens.head, UnknownType)
- buildup(root, tokens.tail)
- }
- if(validComponentName(s)) {
- parse(tokenize(s))
- } else error(s"Cannot convert $s into an expression.")
- }
-
- case class AnnotationException(message: String) extends Exception(message)
-
- /**
- * Named classes associate an annotation with a component in a Firrtl circuit
- */
- trait Named { def name: String }
- case class CircuitName(name: String) extends Named {
- if(!validModuleName(name)) throw AnnotationException(s"Illegal circuit name: $name")
- }
- case class ModuleName(name: String, circuit: CircuitName) extends Named {
- if(!validModuleName(name)) throw AnnotationException(s"Illegal module name: $name")
- }
- case class ComponentName(name: String, module: ModuleName) extends Named {
- if(!validComponentName(name)) throw AnnotationException(s"Illegal component name: $name")
- def expr: Expression = toExp(name)
- }
-
- /**
- * Permissibility defines the range of acceptable changes to the annotated component.
- */
- trait Permissibility {
- def check(from: Named, tos: Seq[Named], which: Annotation): Unit
- }
- /**
- * Annotated component cannot be renamed, expanded, or removed.
- */
- trait Strict extends Permissibility {
- def check(from: Named, tos: Seq[Named], which: Annotation): Unit = tos.size match {
- case 0 =>
- throw new AnnotationException(s"Cannot remove the strict annotation ${which.serialize} on ${from.name}")
- case 1 if from != tos.head =>
- throw new AnnotationException(s"Cannot rename the strict annotation ${which.serialize} on ${from.name} -> ${tos.head.name}")
- case _ =>
- throw new AnnotationException(s"Cannot expand a strict annotation on ${from.name} -> ${tos.map(_.name)}")
- }
- }
-
- /**
- * Annotated component can be renamed, but cannot be expanded or removed.
- */
- trait Rigid extends Permissibility {
- def check(from: Named, tos: Seq[Named], which: Annotation): Unit = tos.size match {
- case 0 => throw new AnnotationException(s"Cannot remove the rigid annotation ${which.serialize} on ${from.name}")
- case 1 =>
- case _ => throw new AnnotationException(s"Cannot expand a rigid annotation on ${from.name} -> ${tos.map(_.name)}")
- }
- }
-
- /**
- * Annotated component can be renamed, and expanded, but not removed.
- */
- trait Firm extends Permissibility {
- def check(from: Named, tos: Seq[Named], which: Annotation): Unit = tos.size match {
- case 0 => throw new AnnotationException(s"Cannot remove the firm annotation ${which.serialize} on ${from.name}")
- case _ =>
- }
- }
-
- /**
- * Annotated component can be renamed, and expanded, and removed.
- */
- trait Loose extends Permissibility {
- def check(from: Named, tos: Seq[Named], which: Annotation): Unit = {}
- }
-
- /**
- * Tenacity defines how the annotation propagates when changes to the
- * annotated component occur.
- */
- trait Tenacity {
- protected def propagate(from: Named, tos: Seq[Named], dup: Named=>Annotation): Seq[Annotation]
- }
-
- /**
- * Annotation propagates to all new components
- */
- trait Sticky extends Tenacity {
- protected def propagate(from: Named, tos: Seq[Named], dup: Named=>Annotation): Seq[Annotation] = tos.map(dup(_))
- }
-
- /**
- * Annotation propagates to the first of all new components
- */
- trait Insistent extends Tenacity {
- protected def propagate(from: Named, tos: Seq[Named], dup: Named=>Annotation): Seq[Annotation] = tos.headOption match {
- case None => Seq.empty
- case Some(n) => Seq(dup(n))
- }
- }
-
- /**
- * Annotation propagates only if there is one new component.
- */
- trait Fickle extends Tenacity {
- protected def propagate(from: Named, tos: Seq[Named], dup: Named=>Annotation): Seq[Annotation] = tos.size match {
- case 1 => Seq(dup(tos.head))
- case _ => Seq.empty
- }
- }
-
- /**
- * Annotation propagates only the new component shares the same name.
- */
- trait Unstable extends Tenacity {
- protected def propagate(from: Named, tos: Seq[Named], dup: Named=>Annotation): Seq[Annotation] = tos.size match {
- case 1 if tos.head == from => Seq(dup(tos.head))
- case _ => Seq.empty
- }
- }
-
- /**
- * Annotation associates with a given named circuit component (target) and a
- * given transformation (transform). Also defined are the legal ranges of changes
- * to the associated component (Permissibility) and how the annotation
- * propagates under such changes (Tenacity). Subclasses must implement the
- * duplicate function to create the same annotation associated with a new
- * component.
- */
- trait Annotation extends Permissibility with Tenacity {
- def target: Named
- def transform: Class[_ <: Transform]
- protected def duplicate(n: Named): Annotation
- def serialize: String = this.toString
- def update(tos: Seq[Named]): Seq[Annotation] = {
- check(target, tos, this)
- propagate(target, tos, duplicate)
- }
- }
-
- /**
- * Container of all annotations for a Firrtl compiler.
- */
- case class AnnotationMap(annotations: Seq[Annotation]) {
- def get(id: Class[_]): Seq[Annotation] = annotations.filter(a => a.transform == id)
- def get(named: Named): Seq[Annotation] = annotations.filter(n => n == named)
- }
-}
-
diff --git a/src/main/scala/firrtl/Compiler.scala b/src/main/scala/firrtl/Compiler.scala
index 2e155885..106c973f 100644
--- a/src/main/scala/firrtl/Compiler.scala
+++ b/src/main/scala/firrtl/Compiler.scala
@@ -4,7 +4,7 @@ package firrtl
import logger.LazyLogging
import java.io.Writer
-import Annotations._
+import annotations._
import firrtl.ir.Circuit
import passes.Pass
@@ -15,6 +15,14 @@ import passes.Pass
*/
case class RenameMap(map: Map[Named, Seq[Named]])
+/**
+ * Container of all annotations for a Firrtl compiler.
+ */
+case class AnnotationMap(annotations: Seq[Annotation]) {
+ def get(id: Class[_]): Seq[Annotation] = annotations.filter(a => a.transform == id)
+ def get(named: Named): Seq[Annotation] = annotations.filter(n => n == named)
+}
+
/** Current State of the Circuit
*
* @constructor Creates a CircuitState object
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala
index e0d65bca..fe484965 100644
--- a/src/main/scala/firrtl/Driver.scala
+++ b/src/main/scala/firrtl/Driver.scala
@@ -2,15 +2,15 @@
package firrtl
-import java.io.FileNotFoundException
-
-import logger.Logger
-
+import scala.collection._
import scala.io.Source
-import Annotations._
-
+import java.io.{File, FileNotFoundException}
+import net.jcazevedo.moultingyaml._
+import logger.Logger
import Parser.{InfoMode, IgnoreInfo}
-import scala.collection._
+import annotations._
+import firrtl.annotations.AnnotationYamlProtocol._
+
/**
* The driver provides methods to access the firrtl compiler.
@@ -72,6 +72,28 @@ object Driver {
}
/**
+ * Load annotation file based on options
+ * @param optionsManager use optionsManager config to load annotation file if it exists
+ * update the firrtlOptions with new annotations if it does
+ */
+ def loadAnnotations(optionsManager: ExecutionOptionsManager with HasFirrtlOptions): Unit = {
+ /*
+ Right now annotations will be looked for always based on the
+ s"$targetDirName/$topName.anno" or s"$annotationFileNameOverride.anno"
+ If found they will be added to the annotations already in the
+ optionsManager.firrtlOptions, duplicates may be created, but this should be ok
+ */
+ val firrtlConfig = optionsManager.firrtlOptions
+ val annotationFileName = firrtlConfig.getAnnotationFileName(optionsManager)
+ val annotationFile = new File(annotationFileName)
+ if(annotationFile.exists) {
+ val annotationsYaml = io.Source.fromFile(annotationFile).getLines().mkString("\n").parseYaml
+ val annotationArray = annotationsYaml.convertTo[Array[Annotation]]
+ optionsManager.firrtlOptions = firrtlConfig.copy(annotations = firrtlConfig.annotations ++ annotationArray)
+ }
+ }
+
+ /**
* Run the firrtl compiler using the provided option
*
* @param optionsManager the desired flags to the compiler
@@ -111,6 +133,8 @@ object Driver {
}
}
+ loadAnnotations(optionsManager)
+
val parsedInput = Parser.parse(firrtlSource, firrtlConfig.infoMode)
val outputBuffer = new java.io.CharArrayWriter
firrtlConfig.compiler.compile(
diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala
index 704992c2..f91f45c5 100644
--- a/src/main/scala/firrtl/ExecutionOptionsManager.scala
+++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala
@@ -2,7 +2,7 @@
package firrtl
-import firrtl.Annotations._
+import firrtl.annotations._
import firrtl.Parser._
import firrtl.passes.memlib.{InferReadWriteAnnotation, ReplSeqMemAnnotation}
import firrtl.passes.clocklist.ClockListAnnotation
@@ -142,7 +142,8 @@ case class FirrtlExecutionOptions(
inferRW: Seq[String] = Seq.empty,
firrtlSource: Option[String] = None,
customTransforms: Seq[Transform] = List.empty,
- annotations: List[Annotation] = List.empty)
+ annotations: List[Annotation] = List.empty,
+ annotationFileNameOverride: String = "")
extends ComposableOptions {
@@ -192,6 +193,15 @@ case class FirrtlExecutionOptions(
def getOutputFileName(optionsManager: ExecutionOptionsManager): String = {
optionsManager.getBuildFileName(outputSuffix, outputFileNameOverride)
}
+ /**
+ * build the annotation file name, taking overriding parameters
+ *
+ * @param optionsManager this is needed to access build function and its common options
+ * @return
+ */
+ def getAnnotationFileName(optionsManager: ExecutionOptionsManager): String = {
+ optionsManager.getBuildFileName("anno", annotationFileNameOverride)
+ }
}
trait HasFirrtlOptions {
@@ -206,7 +216,7 @@ trait HasFirrtlOptions {
.foreach { x =>
firrtlOptions = firrtlOptions.copy(inputFileNameOverride = x)
}.text {
- "use this to override the top name default, default is empty"
+ "use this to override the default input file name , default is empty"
}
parser.opt[String]("output-file")
@@ -215,8 +225,17 @@ trait HasFirrtlOptions {
foreach { x =>
firrtlOptions = firrtlOptions.copy(outputFileNameOverride = x)
}.text {
- "use this to override the default name, default is empty"
- }
+ "use this to override the default output file name, default is empty"
+ }
+
+ parser.opt[String]("annotation-file")
+ .abbr("faf")
+ .valueName ("<output>").
+ foreach { x =>
+ firrtlOptions = firrtlOptions.copy(outputFileNameOverride = x)
+ }.text {
+ "use this to override the default annotation file name, default is empty"
+ }
parser.opt[String]("compiler")
.abbr("X")
diff --git a/src/main/scala/firrtl/annotations/Annotation.scala b/src/main/scala/firrtl/annotations/Annotation.scala
new file mode 100644
index 00000000..5881001f
--- /dev/null
+++ b/src/main/scala/firrtl/annotations/Annotation.scala
@@ -0,0 +1,21 @@
+// See LICENSE for license details.
+
+package firrtl
+package annotations
+
+import firrtl.ir._
+
+case class AnnotationException(message: String) extends Exception(message)
+
+final case class Annotation(target: Named, transform: Class[_ <: Transform], value: String) {
+ val targetString: String = target.serialize
+ val transformClass: String = transform.getName
+ def serialize: String = this.toString
+ def update(tos: Seq[Named]): Seq[Annotation] = {
+ check(target, tos, this)
+ propagate(target, tos, duplicate)
+ }
+ def propagate(from: Named, tos: Seq[Named], dup: Named=>Annotation): Seq[Annotation] = tos.map(dup(_))
+ def check(from: Named, tos: Seq[Named], which: Annotation): Unit = {}
+ def duplicate(n: Named) = new Annotation(n, transform, value)
+}
diff --git a/src/main/scala/firrtl/annotations/AnnotationUtils.scala b/src/main/scala/firrtl/annotations/AnnotationUtils.scala
new file mode 100644
index 00000000..6e6af81d
--- /dev/null
+++ b/src/main/scala/firrtl/annotations/AnnotationUtils.scala
@@ -0,0 +1,74 @@
+// See LICENSE for license details.
+
+package firrtl
+package annotations
+
+import firrtl.ir._
+
+object AnnotationUtils {
+ /** Returns true if a valid Module name */
+ val SerializedModuleName = """([a-zA-Z_][a-zA-Z_0-9~!@#$%^*\-+=?/]*)""".r
+ def validModuleName(s: String): Boolean = s match {
+ case SerializedModuleName(name) => true
+ case _ => false
+ }
+
+ /** Returns true if a valid component/subcomponent name */
+ val SerializedComponentName = """([a-zA-Z_][a-zA-Z_0-9\[\]\.~!@#$%^*\-+=?/]*)""".r
+ def validComponentName(s: String): Boolean = s match {
+ case SerializedComponentName(name) => true
+ case _ => false
+ }
+
+ /** Tokenizes a string with '[', ']', '.' as tokens, e.g.:
+ * "foo.bar[boo.far]" becomes Seq("foo" "." "bar" "[" "boo" "." "far" "]")
+ */
+ def tokenize(s: String): Seq[String] = s.find(c => "[].".contains(c)) match {
+ case Some(_) =>
+ val i = s.indexWhere(c => "[].".contains(c))
+ s.slice(0, i) match {
+ case "" => Seq(s(i).toString) ++ tokenize(s.drop(i + 1))
+ case x => Seq(x, s(i).toString) ++ tokenize(s.drop(i + 1))
+ }
+ case None if s == "" => Nil
+ case None => Seq(s)
+ }
+
+ /** Given a serialized component/subcomponent reference, subindex, subaccess,
+ * or subfield, return the corresponding IR expression.
+ * E.g. "foo.bar" becomes SubField(Reference("foo", UnknownType), "bar", UnknownType)
+ */
+ def toExp(s: String): Expression = {
+ def parse(tokens: Seq[String]): Expression = {
+ val DecPattern = """([1-9]\d*)""".r
+ def findClose(tokens: Seq[String], index: Int, nOpen: Int): Seq[String] = {
+ if(index >= tokens.size) {
+ error("Cannot find closing bracket ]")
+ } else tokens(index) match {
+ case "[" => findClose(tokens, index + 1, nOpen + 1)
+ case "]" if nOpen == 1 => tokens.slice(1, index)
+ case "]" => findClose(tokens, index + 1, nOpen - 1)
+ case _ => findClose(tokens, index + 1, nOpen)
+ }
+ }
+ def buildup(e: Expression, tokens: Seq[String]): Expression = tokens match {
+ case "[" :: tail =>
+ val indexOrAccess = findClose(tokens, 0, 0)
+ val exp = indexOrAccess.head match {
+ case DecPattern(d) => SubIndex(e, d.toInt, UnknownType)
+ case _ => SubAccess(e, parse(indexOrAccess), UnknownType)
+ }
+ buildup(exp, tokens.drop(2 + indexOrAccess.size))
+ case "." :: tail =>
+ buildup(SubField(e, tokens(1), UnknownType), tokens.drop(2))
+ case Nil => e
+ }
+ val root = Reference(tokens.head, UnknownType)
+ buildup(root, tokens.tail)
+ }
+ if(validComponentName(s)) {
+ parse(tokenize(s))
+ } else error(s"Cannot convert $s into an expression.")
+ }
+}
+
diff --git a/src/main/scala/firrtl/annotations/AnnotationYamlProtocol.scala b/src/main/scala/firrtl/annotations/AnnotationYamlProtocol.scala
new file mode 100644
index 00000000..5da00282
--- /dev/null
+++ b/src/main/scala/firrtl/annotations/AnnotationYamlProtocol.scala
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+
+package firrtl
+package annotations
+
+import net.jcazevedo.moultingyaml._
+
+object AnnotationYamlProtocol extends DefaultYamlProtocol {
+ // bottom depends on top
+ implicit object AnnotationYamlFormat extends YamlFormat[Annotation] {
+ def write(a: Annotation) =
+ YamlArray(
+ YamlString(a.targetString),
+ YamlString(a.transformClass),
+ YamlString(a.value))
+
+ def read(value: YamlValue) = {
+ value.asYamlObject.getFields(
+ YamlString("targetString"),
+ YamlString("transformClass"),
+ YamlString("value")) match {
+ case Seq(
+ YamlString(targetString),
+ YamlString(transformClass),
+ YamlString(value)) =>
+ new Annotation(toTarget(targetString), Class.forName(transformClass).asInstanceOf[Class[_ <: Transform]], value)
+ case _ => deserializationError("Color expected")
+ }
+ }
+ def toTarget(string: String) = string.split('.').toSeq match {
+ case Seq(c) => CircuitName(c)
+ case Seq(c, m) => ModuleName(m, CircuitName(c))
+ case Nil => error("BAD")
+ case s => ComponentName(s.drop(2).mkString("."), ModuleName(s(1), CircuitName(s(0))))
+ }
+ }
+}
diff --git a/src/main/scala/firrtl/annotations/Named.scala b/src/main/scala/firrtl/annotations/Named.scala
new file mode 100644
index 00000000..e9b89e75
--- /dev/null
+++ b/src/main/scala/firrtl/annotations/Named.scala
@@ -0,0 +1,31 @@
+// See LICENSE for license details.
+
+package firrtl
+package annotations
+
+import firrtl.ir.Expression
+import AnnotationUtils.{validModuleName, validComponentName, toExp}
+
+/**
+ * Named classes associate an annotation with a component in a Firrtl circuit
+ */
+sealed trait Named {
+ def name: String
+ def serialize: String
+}
+
+final case class CircuitName(name: String) extends Named {
+ if(!validModuleName(name)) throw AnnotationException(s"Illegal circuit name: $name")
+ def serialize: String = name
+}
+
+final case class ModuleName(name: String, circuit: CircuitName) extends Named {
+ if(!validModuleName(name)) throw AnnotationException(s"Illegal module name: $name")
+ def serialize: String = name + "." + circuit.serialize
+}
+
+final case class ComponentName(name: String, module: ModuleName) extends Named {
+ if(!validComponentName(name)) throw AnnotationException(s"Illegal component name: $name")
+ def expr: Expression = toExp(name)
+ def serialize: String = name + "." + module.serialize
+}
diff --git a/src/main/scala/firrtl/passes/Inline.scala b/src/main/scala/firrtl/passes/Inline.scala
index 5c9d4367..002343ac 100644
--- a/src/main/scala/firrtl/passes/Inline.scala
+++ b/src/main/scala/firrtl/passes/Inline.scala
@@ -5,15 +5,19 @@ package passes
import firrtl.ir._
import firrtl.Mappers._
-import firrtl.Annotations._
+import firrtl.annotations._
// Datastructures
import scala.collection.mutable
// Tags an annotation to be consumed by this pass
-case class InlineAnnotation(target: Named) extends Annotation with Loose with Unstable {
- def duplicate(n: Named) = this.copy(target=n)
- def transform = classOf[InlineInstances]
+object InlineAnnotation {
+ def apply(target: Named): Annotation = Annotation(target, classOf[InlineInstances], "")
+
+ def unapply(a: Annotation): Option[Named] = a match {
+ case Annotation(named, t, _) if t == classOf[InlineInstances] => Some(named)
+ case _ => None
+ }
}
// Only use on legal Firrtl. Specifically, the restriction of
diff --git a/src/main/scala/firrtl/passes/clocklist/ClockList.scala b/src/main/scala/firrtl/passes/clocklist/ClockList.scala
index d0920406..231afbdd 100644
--- a/src/main/scala/firrtl/passes/clocklist/ClockList.scala
+++ b/src/main/scala/firrtl/passes/clocklist/ClockList.scala
@@ -5,7 +5,7 @@ package clocklist
import firrtl._
import firrtl.ir._
-import Annotations._
+import annotations._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter, Writer}
import wiring.WiringUtils.{getChildrenMap, countInstances, ChildrenMap, getLineage}
diff --git a/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala b/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
index b901e4e8..8b5a0627 100644
--- a/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
+++ b/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
@@ -5,7 +5,7 @@ package clocklist
import firrtl._
import firrtl.ir._
-import Annotations._
+import annotations._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter, Writer}
import wiring.WiringUtils.{getChildrenMap, countInstances, ChildrenMap, getLineage}
@@ -16,17 +16,8 @@ import memlib.AnalysisUtils._
import memlib._
import Mappers._
-case class ClockListAnnotation(target: ModuleName, outputConfig: String)
- extends Annotation with Loose with Unstable {
- def transform = classOf[ClockListTransform]
- def duplicate(n: Named) = n match {
- case m: ModuleName => this.copy(target = m, outputConfig = outputConfig)
- case _ => error("Clocklist can only annotate a module.")
- }
-}
-
object ClockListAnnotation {
- def apply(t: String) = {
+ def apply(t: String): Annotation = {
val usage = """
[Optional] ClockList
List which signal drives each clock of every descendent of specified module
@@ -55,7 +46,16 @@ Usage:
case None =>
}
val target = ModuleName(passModule, CircuitName(passCircuit))
- new ClockListAnnotation(target, outputConfig)
+ Annotation(target, classOf[ClockListTransform], outputConfig)
+ }
+
+ def apply(target: ModuleName, outputConfig: String): Annotation =
+ Annotation(target, classOf[ClockListTransform], outputConfig)
+
+ def unapply(a: Annotation): Option[(ModuleName, String)] = a match {
+ case Annotation(ModuleName(m, c), t, outputConfig) if t == classOf[ClockListTransform] =>
+ Some((ModuleName(m, c), outputConfig))
+ case _ => None
}
}
diff --git a/src/main/scala/firrtl/passes/clocklist/ClockListUtils.scala b/src/main/scala/firrtl/passes/clocklist/ClockListUtils.scala
index 04e99d99..b81d0c7e 100644
--- a/src/main/scala/firrtl/passes/clocklist/ClockListUtils.scala
+++ b/src/main/scala/firrtl/passes/clocklist/ClockListUtils.scala
@@ -5,7 +5,7 @@ package clocklist
import firrtl._
import firrtl.ir._
-import Annotations._
+import annotations._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter, Writer}
import wiring.WiringUtils.{getChildrenMap, countInstances, ChildrenMap, getLineage}
diff --git a/src/main/scala/firrtl/passes/clocklist/RemoveAllButClocks.scala b/src/main/scala/firrtl/passes/clocklist/RemoveAllButClocks.scala
index da1129bc..feb7f42e 100644
--- a/src/main/scala/firrtl/passes/clocklist/RemoveAllButClocks.scala
+++ b/src/main/scala/firrtl/passes/clocklist/RemoveAllButClocks.scala
@@ -5,7 +5,7 @@ package clocklist
import firrtl._
import firrtl.ir._
-import Annotations._
+import annotations._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter, Writer}
import wiring.WiringUtils.{getChildrenMap, countInstances, ChildrenMap, getLineage}
diff --git a/src/main/scala/firrtl/passes/memlib/DecorateMems.scala b/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
index d73fbc91..668bc2e5 100644
--- a/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
+++ b/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
@@ -4,7 +4,7 @@ package firrtl
package passes
package memlib
import ir._
-import Annotations._
+import annotations._
import wiring._
class CreateMemoryAnnotations(reader: Option[YamlFileReader]) extends Transform {
diff --git a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
index 6b56c5e8..2501ba04 100644
--- a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
+++ b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
@@ -11,12 +11,16 @@ import firrtl.Utils.{one, zero, BoolType}
import MemPortUtils.memPortField
import firrtl.passes.memlib.AnalysisUtils.{Connects, getConnects, getOrigin}
import WrappedExpression.weq
-import Annotations._
+import annotations._
-case class InferReadWriteAnnotation(t: String) extends Annotation with Loose with Unstable {
- val target = CircuitName(t)
- def duplicate(n: Named) = this.copy(t=n.name)
- def transform = classOf[InferReadWrite]
+object InferReadWriteAnnotation {
+ def apply(t: String) = Annotation(CircuitName(t), classOf[InferReadWrite], "")
+ def apply(target: CircuitName) = Annotation(target, classOf[InferReadWrite], "")
+ def unapply(a: Annotation): Option[(CircuitName)] = a match {
+ case Annotation(CircuitName(t), transform, "") if transform == classOf[InferReadWrite] =>
+ Some(CircuitName(t))
+ case _ => None
+ }
}
// This pass examine the enable signals of the read & write ports of memories
@@ -155,6 +159,7 @@ class InferReadWrite extends Transform with PassBased {
)
def execute(state: CircuitState): CircuitState = getMyAnnotations(state) match {
case Nil => CircuitState(state.circuit, state.form)
- case Seq(InferReadWriteAnnotation(_)) => CircuitState(runPasses(state.circuit), state.form)
+ case Seq(InferReadWriteAnnotation(CircuitName(state.circuit.main))) =>
+ CircuitState(runPasses(state.circuit), state.form)
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
index 30196fad..44dad557 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
@@ -10,18 +10,17 @@ import firrtl.Mappers._
import MemPortUtils.{MemPortMap, Modules}
import MemTransformUtils._
import AnalysisUtils._
-import Annotations._
+import firrtl.annotations._
import wiring._
/** Annotates the name of the pin to add for WiringTransform
*/
-case class PinAnnotation(target: CircuitName, pins: Seq[String]) extends Annotation with Loose with Unstable {
- def transform = classOf[ReplaceMemMacros]
- def duplicate(n: Named) = n match {
- case n: CircuitName => this.copy(target = n)
- case _ => throwInternalError
+object PinAnnotation {
+ def apply(target: CircuitName, pins: Seq[String]): Annotation = {
+ Annotation(target, classOf[ReplaceMemMacros], pins.foldLeft("") { (str, p) => str + "pin:" + p + " " } )
}
+ val matcher = "pin:([^ ]+)".r
}
/** Replace DefAnnotatedMemory with memory blackbox + wrapper + conf file.
@@ -220,10 +219,11 @@ class ReplaceMemMacros(writer: ConfWriter) extends Transform {
writer.serialize()
val pins = getMyAnnotations(state) match {
case Nil => Nil
- case Seq(p) => p match {
- case PinAnnotation(c, pins) => pins
- case _ => error(s"Bad Annotation: ${p}")
- }
+ case Seq(Annotation(c, t, string)) =>
+ PinAnnotation.matcher.findAllIn(string).toSeq match {
+ case Nil => error(s"Bad Annotation: ${Annotation(c, t, string)}")
+ case seq => seq
+ }
case _ => throwInternalError
}
val annos = pins.foldLeft(Seq[Annotation]()) { (seq, pin) =>
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
index 67b81160..f8f76a49 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
@@ -5,7 +5,7 @@ package memlib
import firrtl._
import firrtl.ir._
-import Annotations._
+import firrtl.annotations._
import AnalysisUtils._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter}
@@ -64,9 +64,9 @@ class ConfWriter(filename: String) {
}
}
-case class ReplSeqMemAnnotation(t: String) extends Annotation with Loose with Unstable {
-
- val usage = """
+object ReplSeqMemAnnotation {
+ def apply(t: String): Annotation = {
+ val usage = """
[Optional] ReplSeqMem
Pass to replace sequential memories with blackboxes + configuration file
@@ -82,18 +82,29 @@ Optional Arguments:
-i<filename> Specify the input configuration file (for additional optimizations)
"""
- val passOptions = PassConfigUtil.getPassOptions(t, usage)
- val outputConfig = passOptions.getOrElse(
- OutputConfigFileName,
- error("No output config file provided for ReplSeqMem!" + usage)
- )
- val passCircuit = passOptions.getOrElse(
- PassCircuitName,
- error("No circuit name specified for ReplSeqMem!" + usage)
- )
- val target = CircuitName(passCircuit)
- def duplicate(n: Named) = this copy (t = t.replace(s"-c:$passCircuit", s"-c:${n.name}"))
- def transform = classOf[ReplSeqMem]
+ val passOptions = PassConfigUtil.getPassOptions(t, usage)
+ val outputConfig = passOptions.getOrElse(
+ OutputConfigFileName,
+ error("No output config file provided for ReplSeqMem!" + usage)
+ )
+ val inputFileName = PassConfigUtil.getPassOptions(t).getOrElse(InputConfigFileName, "")
+ val passCircuit = passOptions.getOrElse(
+ PassCircuitName,
+ error("No circuit name specified for ReplSeqMem!" + usage)
+ )
+ val target = CircuitName(passCircuit)
+ Annotation(target, classOf[ReplSeqMem], s"$inputFileName $outputConfig")
+ }
+
+ def apply(target: CircuitName, inputFileName: String, outputConfig: String): Annotation =
+ Annotation(target, classOf[ReplSeqMem], s"$inputFileName $outputConfig")
+
+ private val matcher = "([^ ]*) ([^ ]+)".r
+ def unapply(a: Annotation): Option[(CircuitName, String, String)] = a match {
+ case Annotation(CircuitName(c), t, matcher(inputFileName, outputConfig)) if t == classOf[ReplSeqMem] =>
+ Some((CircuitName(c), inputFileName, outputConfig))
+ case _ => None
+ }
}
class SimpleTransform(p: Pass, form: CircuitForm) extends Transform {
@@ -139,14 +150,13 @@ class ReplSeqMem extends Transform with SimpleRun {
getMyAnnotations(state) match {
case Nil => state.copy(annotations = None) // Do nothing if there are no annotations
case p => (p.collectFirst { case a if (a.target == CircuitName(state.circuit.main)) => a }) match {
- case Some(ReplSeqMemAnnotation(t)) =>
- val inputFileName = PassConfigUtil.getPassOptions(t).getOrElse(InputConfigFileName, "")
+ case Some(ReplSeqMemAnnotation(target, inputFileName, outputConfig)) =>
val inConfigFile = {
if (inputFileName.isEmpty) None
else if (new File(inputFileName).exists) Some(new YamlFileReader(inputFileName))
else error("Input configuration file does not exist!")
}
- val outConfigFile = new ConfWriter(PassConfigUtil.getPassOptions(t)(OutputConfigFileName))
+ val outConfigFile = new ConfWriter(outputConfig)
run(state, passSeq(inConfigFile, outConfigFile))
case _ => error("Unexpected transform annotation")
}
diff --git a/src/main/scala/firrtl/passes/wiring/Wiring.scala b/src/main/scala/firrtl/passes/wiring/Wiring.scala
index 1ced07eb..f5da4c06 100644
--- a/src/main/scala/firrtl/passes/wiring/Wiring.scala
+++ b/src/main/scala/firrtl/passes/wiring/Wiring.scala
@@ -8,7 +8,8 @@ import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
import scala.collection.mutable
-import firrtl.Annotations._
+import firrtl.annotations._
+import firrtl.annotations.AnnotationUtils._
import WiringUtils._
case class WiringException(msg: String) extends PassException(msg)
diff --git a/src/main/scala/firrtl/passes/wiring/WiringTransform.scala b/src/main/scala/firrtl/passes/wiring/WiringTransform.scala
index 5c251d6d..9528c0b7 100644
--- a/src/main/scala/firrtl/passes/wiring/WiringTransform.scala
+++ b/src/main/scala/firrtl/passes/wiring/WiringTransform.scala
@@ -8,37 +8,43 @@ import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
import scala.collection.mutable
-import firrtl.Annotations._
+import firrtl.annotations._
import WiringUtils._
/** A component, e.g. register etc. Must be declared only once under the TopAnnotation
*/
-case class SourceAnnotation(target: ComponentName, pin: String) extends Annotation with Loose with Unstable {
- def transform = classOf[WiringTransform]
- def duplicate(n: Named) = n match {
- case n: ComponentName => this.copy(target = n)
- case _ => throwInternalError
+object SourceAnnotation {
+ def apply(target: ComponentName, pin: String): Annotation = Annotation(target, classOf[WiringTransform], s"source $pin")
+
+ private val matcher = "source (.+)".r
+ def unapply(a: Annotation): Option[(ComponentName, String)] = a match {
+ case Annotation(ComponentName(n, m), _, matcher(pin)) => Some((ComponentName(n, m), pin))
+ case _ => None
}
}
/** A module, e.g. ExtModule etc., that should add the input pin
*/
-case class SinkAnnotation(target: ModuleName, pin: String) extends Annotation with Loose with Unstable {
- def transform = classOf[WiringTransform]
- def duplicate(n: Named) = n match {
- case n: ModuleName => this.copy(target = n)
- case _ => throwInternalError
+object SinkAnnotation {
+ def apply(target: ModuleName, pin: String): Annotation = Annotation(target, classOf[WiringTransform], s"sink $pin")
+
+ private val matcher = "sink (.+)".r
+ def unapply(a: Annotation): Option[(ModuleName, String)] = a match {
+ case Annotation(ModuleName(n, c), _, matcher(pin)) => Some((ModuleName(n, c), pin))
+ case _ => None
}
}
/** A module under which all sink module must be declared, and there is only
* one source component
*/
-case class TopAnnotation(target: ModuleName, pin: String) extends Annotation with Loose with Unstable {
- def transform = classOf[WiringTransform]
- def duplicate(n: Named) = n match {
- case n: ModuleName => this.copy(target = n)
- case _ => throwInternalError
+object TopAnnotation {
+ def apply(target: ModuleName, pin: String): Annotation = Annotation(target, classOf[WiringTransform], s"top $pin")
+
+ private val matcher = "top (.+)".r
+ def unapply(a: Annotation): Option[(ModuleName, String)] = a match {
+ case Annotation(ModuleName(n, c), _, matcher(pin)) => Some((ModuleName(n, c), pin))
+ case _ => None
}
}
@@ -64,20 +70,18 @@ class WiringTransform extends Transform with SimpleRun {
ResolveGenders)
def execute(state: CircuitState): CircuitState = getMyAnnotations(state) match {
case Nil => CircuitState(state.circuit, state.form)
- case p =>
- // Pin to value
+ case p =>
val sinks = mutable.HashMap[String, Set[String]]()
val sources = mutable.HashMap[String, String]()
val tops = mutable.HashMap[String, String]()
val comp = mutable.HashMap[String, String]()
- p.foreach { a =>
- a match {
- case SinkAnnotation(m, pin) => sinks(pin) = sinks.getOrElse(pin, Set.empty) + m.name
- case SourceAnnotation(c, pin) =>
- sources(pin) = c.module.name
- comp(pin) = c.name
- case TopAnnotation(m, pin) => tops(pin) = m.name
- }
+ p.foreach {
+ case SinkAnnotation(m, pin) =>
+ sinks(pin) = sinks.getOrElse(pin, Set.empty) + m.name
+ case SourceAnnotation(c, pin) =>
+ sources(pin) = c.module.name
+ comp(pin) = c.name
+ case TopAnnotation(m, pin) => tops(pin) = m.name
}
(sources.size, tops.size, sinks.size, comp.size) match {
case (0, 0, p, 0) => state.copy(annotations = None)
diff --git a/src/main/scala/firrtl/passes/wiring/WiringUtils.scala b/src/main/scala/firrtl/passes/wiring/WiringUtils.scala
index 2527ccbe..29c93ca7 100644
--- a/src/main/scala/firrtl/passes/wiring/WiringUtils.scala
+++ b/src/main/scala/firrtl/passes/wiring/WiringUtils.scala
@@ -8,7 +8,7 @@ import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
import scala.collection.mutable
-import firrtl.Annotations._
+import firrtl.annotations._
import WiringUtils._
/** Declaration kind in lineage (e.g. input port, output port, wire)
diff --git a/src/main/scala/firrtl/transforms/Dedup.scala b/src/main/scala/firrtl/transforms/Dedup.scala
index a9d3b4c9..0d9be831 100644
--- a/src/main/scala/firrtl/transforms/Dedup.scala
+++ b/src/main/scala/firrtl/transforms/Dedup.scala
@@ -5,18 +5,12 @@ package transforms
import firrtl.ir._
import firrtl.Mappers._
-import firrtl.Annotations._
+import firrtl.annotations._
import firrtl.passes.PassException
// Datastructures
import scala.collection.mutable
-// Tags an annotation to be consumed by this pass
-case class DedupAnnotation(target: Named) extends Annotation with Loose with Unstable {
- def duplicate(n: Named) = this.copy(target=n)
- def transform = classOf[DedupModules]
-}
-
// Only use on legal Firrtl. Specifically, the restriction of
// instance loops must have been checked, or else this pass can
// infinitely recurse
diff --git a/src/test/resources/annotations/SampleAnnotations.anno b/src/test/resources/annotations/SampleAnnotations.anno
new file mode 100644
index 00000000..8fa9f44f
--- /dev/null
+++ b/src/test/resources/annotations/SampleAnnotations.anno
@@ -0,0 +1,30 @@
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModC
+ value: ModC.this params 16 32
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModC.io.out
+ value: ModuleC(16,32) width < 32
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModA
+ value: ModA.this
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModA.io.out
+ value: inside ModA.io.out params 64,64
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModC_1
+ value: ModC.this params 42 77
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModC_1.io.out
+ value: ModuleC(42,77) width < 77
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModB.io.out
+ value: inside ModB.io.out params 32,48
+- transformClass: firrtl.passes.InlineInstances
+ targetString: TopOfDiamond
+ value: |-
+ TopOfDiamond
+ With
+ Some new lines
+- transformClass: firrtl.passes.InlineInstances
+ targetString: ModB.io.in
+ value: TopOfDiamond.moduleB.io.in
diff --git a/src/test/scala/firrtlTests/AnnotationTests.scala b/src/test/scala/firrtlTests/AnnotationTests.scala
index a0a935a9..9ffbbd85 100644
--- a/src/test/scala/firrtlTests/AnnotationTests.scala
+++ b/src/test/scala/firrtlTests/AnnotationTests.scala
@@ -9,7 +9,7 @@ import org.scalatest.Matchers
import org.scalatest.junit.JUnitRunner
import firrtl.ir.Circuit
-import firrtl.Parser
+import firrtl.{Parser, AnnotationMap}
import firrtl.{
CircuitState,
ResolveAndCheck,
@@ -20,22 +20,13 @@ import firrtl.{
VerilogCompiler,
Transform
}
-import firrtl.Annotations.{
+import firrtl.annotations.{
Named,
CircuitName,
ModuleName,
ComponentName,
AnnotationException,
- Annotation,
- Strict,
- Rigid,
- Firm,
- Loose,
- Sticky,
- Insistent,
- Fickle,
- Unstable,
- AnnotationMap
+ Annotation
}
/**
@@ -79,12 +70,8 @@ class AnnotationTests extends AnnotationSpec with Matchers {
val cName = ComponentName("c", mName)
"Loose and Sticky annotation on a node" should "pass through" in {
- case class TestAnnotation(target: Named) extends Annotation with Loose with Sticky {
- def duplicate(to: Named) = this.copy(target=to)
- def transform = classOf[Transform]
- }
val w = new StringWriter()
- val ta = TestAnnotation(cName)
+ val ta = Annotation(cName, classOf[Transform], "")
execute(w, getAMap(ta), input, ta)
}
}
diff --git a/src/test/scala/firrtlTests/AttachSpec.scala b/src/test/scala/firrtlTests/AttachSpec.scala
index d9912ae2..c3df4232 100644
--- a/src/test/scala/firrtlTests/AttachSpec.scala
+++ b/src/test/scala/firrtlTests/AttachSpec.scala
@@ -6,7 +6,7 @@ import java.io._
import org.scalatest._
import org.scalatest.prop._
import firrtl._
-import firrtl.Annotations._
+import firrtl.annotations._
import firrtl.ir.Circuit
import firrtl.passes._
import firrtl.Parser.IgnoreInfo
diff --git a/src/test/scala/firrtlTests/CInferMDirSpec.scala b/src/test/scala/firrtlTests/CInferMDirSpec.scala
index d3c104f5..1385b29d 100644
--- a/src/test/scala/firrtlTests/CInferMDirSpec.scala
+++ b/src/test/scala/firrtlTests/CInferMDirSpec.scala
@@ -6,7 +6,7 @@ import firrtl._
import firrtl.ir._
import firrtl.passes._
import firrtl.Mappers._
-import Annotations._
+import annotations._
class CInferMDir extends LowTransformSpec {
object CInferMDirCheckPass extends Pass {
diff --git a/src/test/scala/firrtlTests/ChirrtlMemSpec.scala b/src/test/scala/firrtlTests/ChirrtlMemSpec.scala
index 2166e9cf..3d8c9825 100644
--- a/src/test/scala/firrtlTests/ChirrtlMemSpec.scala
+++ b/src/test/scala/firrtlTests/ChirrtlMemSpec.scala
@@ -6,7 +6,7 @@ import firrtl._
import firrtl.ir._
import firrtl.passes._
import firrtl.Mappers._
-import Annotations._
+import annotations._
class ChirrtlMemSpec extends LowTransformSpec {
object MemEnableCheckPass extends Pass {
diff --git a/src/test/scala/firrtlTests/ClockListTests.scala b/src/test/scala/firrtlTests/ClockListTests.scala
index ddad7235..9069c145 100644
--- a/src/test/scala/firrtlTests/ClockListTests.scala
+++ b/src/test/scala/firrtlTests/ClockListTests.scala
@@ -7,7 +7,7 @@ import firrtl._
import firrtl.ir.Circuit
import firrtl.passes._
import firrtl.Parser.IgnoreInfo
-import Annotations._
+import annotations._
import clocklist._
class ClockListTests extends FirrtlFlatSpec {
diff --git a/src/test/scala/firrtlTests/DriverSpec.scala b/src/test/scala/firrtlTests/DriverSpec.scala
index 3ff7bed3..f0b5e403 100644
--- a/src/test/scala/firrtlTests/DriverSpec.scala
+++ b/src/test/scala/firrtlTests/DriverSpec.scala
@@ -4,7 +4,12 @@ package firrtlTests
import java.io.File
-import firrtl.passes.memlib.{InferReadWriteAnnotation, ReplSeqMemAnnotation}
+import firrtl.annotations.Annotation
+import org.scalatest.{Matchers, FreeSpec}
+
+import firrtl._
+import firrtl.passes.InlineInstances
+import firrtl.passes.memlib.{ReplSeqMem, InferReadWrite}
import org.scalatest.{Matchers, FreeSpec}
import firrtl._
@@ -92,7 +97,7 @@ class DriverSpec extends FreeSpec with Matchers {
val firrtlOptions = optionsManager.firrtlOptions
firrtlOptions.annotations.length should be (3)
firrtlOptions.annotations.foreach { annotation =>
- annotation shouldBe a [passes.InlineAnnotation]
+ annotation.transform shouldBe classOf[InlineInstances]
}
}
"infer-rw annotation" in {
@@ -105,7 +110,7 @@ class DriverSpec extends FreeSpec with Matchers {
val firrtlOptions = optionsManager.firrtlOptions
firrtlOptions.annotations.length should be (1)
firrtlOptions.annotations.foreach { annotation =>
- annotation shouldBe a [InferReadWriteAnnotation]
+ annotation.transform shouldBe classOf[InferReadWrite]
}
}
"repl-seq-mem annotation" in {
@@ -116,15 +121,28 @@ class DriverSpec extends FreeSpec with Matchers {
) should be (true)
val firrtlOptions = optionsManager.firrtlOptions
-
firrtlOptions.annotations.length should be (1)
firrtlOptions.annotations.foreach { annotation =>
- annotation shouldBe a [ReplSeqMemAnnotation]
+ annotation.transform shouldBe classOf[ReplSeqMem]
}
}
}
}
+ "Annotations can be read from a file" in {
+ val optionsManager = new ExecutionOptionsManager("test") with HasFirrtlOptions {
+ commonOptions = commonOptions.copy(topName = "a.fir")
+ firrtlOptions = firrtlOptions.copy(
+ annotationFileNameOverride = "src/test/resources/annotations/SampleAnnotations"
+ )
+ }
+ optionsManager.firrtlOptions.annotations.length should be (0)
+ Driver.loadAnnotations(optionsManager)
+ optionsManager.firrtlOptions.annotations.length should be (9)
+
+ optionsManager.firrtlOptions.annotations.head.transformClass should be ("firrtl.passes.InlineInstances")
+ }
+
val input =
"""
|circuit Dummy :
diff --git a/src/test/scala/firrtlTests/FirrtlSpec.scala b/src/test/scala/firrtlTests/FirrtlSpec.scala
index c46ecdb7..90db3524 100644
--- a/src/test/scala/firrtlTests/FirrtlSpec.scala
+++ b/src/test/scala/firrtlTests/FirrtlSpec.scala
@@ -12,7 +12,7 @@ import scala.io.Source
import firrtl._
import firrtl.Parser.IgnoreInfo
-import firrtl.Annotations.AnnotationMap
+import firrtl.annotations
// This trait is borrowed from Chisel3, ideally this code should only exist in one location
trait BackendCompilationUtilities {
diff --git a/src/test/scala/firrtlTests/InferReadWriteSpec.scala b/src/test/scala/firrtlTests/InferReadWriteSpec.scala
index cc840981..b92feacd 100644
--- a/src/test/scala/firrtlTests/InferReadWriteSpec.scala
+++ b/src/test/scala/firrtlTests/InferReadWriteSpec.scala
@@ -6,7 +6,7 @@ import firrtl._
import firrtl.ir._
import firrtl.passes._
import firrtl.Mappers._
-import Annotations._
+import annotations._
class InferReadWriteSpec extends SimpleTransformSpec {
class InferReadWriteCheckException extends PassException(
diff --git a/src/test/scala/firrtlTests/InlineInstancesTests.scala b/src/test/scala/firrtlTests/InlineInstancesTests.scala
index 92ed1195..a3e2b38d 100644
--- a/src/test/scala/firrtlTests/InlineInstancesTests.scala
+++ b/src/test/scala/firrtlTests/InlineInstancesTests.scala
@@ -9,15 +9,14 @@ import org.scalatest.Matchers
import org.scalatest.junit.JUnitRunner
import firrtl.ir.Circuit
-import firrtl.Parser
+import firrtl.{Parser, AnnotationMap}
import firrtl.passes.PassExceptions
-import firrtl.Annotations.{
+import firrtl.annotations.{
Named,
CircuitName,
ModuleName,
ComponentName,
- Annotation,
- AnnotationMap
+ Annotation
}
import firrtl.passes.{InlineInstances, InlineAnnotation}
diff --git a/src/test/scala/firrtlTests/MultiThreadingSpec.scala b/src/test/scala/firrtlTests/MultiThreadingSpec.scala
index b2934314..169aa6b2 100644
--- a/src/test/scala/firrtlTests/MultiThreadingSpec.scala
+++ b/src/test/scala/firrtlTests/MultiThreadingSpec.scala
@@ -2,7 +2,7 @@
package firrtlTests
-import firrtl.{ChirrtlForm, CircuitState, Compiler, Annotations}
+import firrtl.{ChirrtlForm, CircuitState, Compiler, annotations}
import scala.concurrent.{Future, Await, ExecutionContext}
import scala.concurrent.duration.Duration
diff --git a/src/test/scala/firrtlTests/PassTests.scala b/src/test/scala/firrtlTests/PassTests.scala
index 444be732..7fa67153 100644
--- a/src/test/scala/firrtlTests/PassTests.scala
+++ b/src/test/scala/firrtlTests/PassTests.scala
@@ -11,6 +11,7 @@ import firrtl.Parser.IgnoreInfo
import firrtl.passes.{Pass, PassExceptions, RemoveEmpty}
import firrtl.{
Transform,
+ AnnotationMap,
PassBasedTransform,
CircuitState,
CircuitForm,
@@ -28,7 +29,6 @@ import firrtl.{
Compiler,
Parser
}
-import firrtl.Annotations.AnnotationMap
// An example methodology for testing Firrtl Passes
diff --git a/src/test/scala/firrtlTests/ReplSeqMemTests.scala b/src/test/scala/firrtlTests/ReplSeqMemTests.scala
index c4ce6975..2cde085a 100644
--- a/src/test/scala/firrtlTests/ReplSeqMemTests.scala
+++ b/src/test/scala/firrtlTests/ReplSeqMemTests.scala
@@ -5,7 +5,7 @@ package firrtlTests
import firrtl._
import firrtl.passes._
import firrtl.passes.memlib._
-import Annotations._
+import annotations._
class ReplSeqMemSpec extends SimpleTransformSpec {
def transforms = Seq(
diff --git a/src/test/scala/firrtlTests/VerilogEmitterTests.scala b/src/test/scala/firrtlTests/VerilogEmitterTests.scala
index 2a1723f3..39592269 100644
--- a/src/test/scala/firrtlTests/VerilogEmitterTests.scala
+++ b/src/test/scala/firrtlTests/VerilogEmitterTests.scala
@@ -6,7 +6,7 @@ import java.io._
import org.scalatest._
import org.scalatest.prop._
import firrtl._
-import firrtl.Annotations._
+import firrtl.annotations._
import firrtl.ir.Circuit
import firrtl.passes._
import firrtl.Parser.IgnoreInfo
diff --git a/src/test/scala/firrtlTests/WiringTests.scala b/src/test/scala/firrtlTests/WiringTests.scala
index b5116f90..e8143741 100644
--- a/src/test/scala/firrtlTests/WiringTests.scala
+++ b/src/test/scala/firrtlTests/WiringTests.scala
@@ -9,7 +9,7 @@ import firrtl._
import firrtl.ir.Circuit
import firrtl.passes._
import firrtl.Parser.IgnoreInfo
-import Annotations._
+import annotations._
import wiring.WiringUtils._
import wiring._
diff --git a/src/test/scala/firrtlTests/fixed/FixedPointMathSpec.scala b/src/test/scala/firrtlTests/fixed/FixedPointMathSpec.scala
index 4a87290d..0c30b59e 100644
--- a/src/test/scala/firrtlTests/fixed/FixedPointMathSpec.scala
+++ b/src/test/scala/firrtlTests/fixed/FixedPointMathSpec.scala
@@ -4,8 +4,7 @@ package firrtlTests.fixed
import java.io.StringWriter
-import firrtl.Annotations.AnnotationMap
-import firrtl.{CircuitState, ChirrtlForm, LowFirrtlCompiler, Parser}
+import firrtl.{CircuitState, ChirrtlForm, LowFirrtlCompiler, Parser, AnnotationMap}
import firrtl.Parser.IgnoreInfo
import firrtlTests.FirrtlFlatSpec
diff --git a/src/test/scala/firrtlTests/fixed/RemoveFixedTypeSpec.scala b/src/test/scala/firrtlTests/fixed/RemoveFixedTypeSpec.scala
index f5105059..6bd06f10 100644
--- a/src/test/scala/firrtlTests/fixed/RemoveFixedTypeSpec.scala
+++ b/src/test/scala/firrtlTests/fixed/RemoveFixedTypeSpec.scala
@@ -3,7 +3,6 @@
package firrtlTests
package fixed
-import firrtl.Annotations.AnnotationMap
import firrtl._
import firrtl.ir.Circuit
import firrtl.passes._
diff --git a/src/test/scala/firrtlTests/transforms/DedupTests.scala b/src/test/scala/firrtlTests/transforms/DedupTests.scala
index bea352ef..1bcd711c 100644
--- a/src/test/scala/firrtlTests/transforms/DedupTests.scala
+++ b/src/test/scala/firrtlTests/transforms/DedupTests.scala
@@ -10,15 +10,14 @@ import org.scalatest.Matchers
import org.scalatest.junit.JUnitRunner
import firrtl.ir.Circuit
-import firrtl.Parser
+import firrtl.{Parser, AnnotationMap}
import firrtl.passes.PassExceptions
-import firrtl.Annotations.{
+import firrtl.annotations.{
Named,
CircuitName,
- Annotation,
- AnnotationMap
+ Annotation
}
-import firrtl.transforms.{DedupModules, DedupAnnotation}
+import firrtl.transforms.DedupModules
/**