aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Lawson2016-12-14 17:09:51 -0800
committerGitHub2016-12-14 17:09:51 -0800
commit44146d59e19fb3697a6da3c834af34a1d45160e3 (patch)
treef1c77c9ac2bc2abe039609c5a47dc9078f7effed /src
parent73529eda60a3e411f3270c2bf7097234a4901ab0 (diff)
parent454d4637a45b5d70772e2831d2dc5af7864d806c (diff)
Merge branch 'master' into addmiddlefirrtlcompiler
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/transforms/Dedup.scala32
-rw-r--r--src/test/scala/firrtlTests/transforms/DedupTests.scala32
2 files changed, 59 insertions, 5 deletions
diff --git a/src/main/scala/firrtl/transforms/Dedup.scala b/src/main/scala/firrtl/transforms/Dedup.scala
index 60a5cfc8..36bc6f66 100644
--- a/src/main/scala/firrtl/transforms/Dedup.scala
+++ b/src/main/scala/firrtl/transforms/Dedup.scala
@@ -11,14 +11,34 @@ import firrtl.passes.PassException
// Datastructures
import scala.collection.mutable
+
+/** A component, e.g. register etc. Must be declared only once under the TopAnnotation
+ */
+object NoDedupAnnotation {
+ def apply(target: ModuleName): Annotation = Annotation(target, classOf[DedupModules], s"nodedup!")
+
+ def unapply(a: Annotation): Option[ModuleName] = a match {
+ case Annotation(ModuleName(n, c), _, "nodedup!") => Some(ModuleName(n, c))
+ case _ => None
+ }
+}
+
+
// Only use on legal Firrtl. Specifically, the restriction of
// instance loops must have been checked, or else this pass can
// infinitely recurse
class DedupModules extends Transform {
def inputForm = HighForm
def outputForm = HighForm
- def execute(state: CircuitState): CircuitState = CircuitState(run(state.circuit), state.form)
- def run(c: Circuit): Circuit = {
+ def execute(state: CircuitState): CircuitState = {
+ getMyAnnotations(state) match {
+ case Nil => CircuitState(run(state.circuit, Seq.empty), state.form)
+ case annos =>
+ val noDedups = annos.collect { case NoDedupAnnotation(ModuleName(m, c)) => m }
+ CircuitState(run(state.circuit, noDedups), state.form)
+ }
+ }
+ def run(c: Circuit, noDedups: Seq[String]): Circuit = {
val moduleOrder = mutable.ArrayBuffer.empty[String]
val moduleMap = c.modules.map(m => m.name -> m).toMap
def hasInstance(b: Statement): Boolean = {
@@ -85,11 +105,15 @@ class DedupModules extends Transform {
val mx = m map fixInstance
val mxx = (mx map removeInfo) map removePortInfo
+
+ // If shouldn't dedup, just make it fail to be the same to any other modules
+ val unique = if (!noDedups.contains(mxx.name)) "" else mxx.name
+
val string = mxx match {
case Module(i, n, ps, b) =>
- ps.map(_.serialize).mkString + b.serialize
+ ps.map(_.serialize).mkString + b.serialize + unique
case ExtModule(i, n, ps, dn, p) =>
- ps.map(_.serialize).mkString + dn + p.map(_.serialize).mkString
+ ps.map(_.serialize).mkString + dn + p.map(_.serialize).mkString + unique
}
dedupModules.get(string) match {
case Some(dupname) =>
diff --git a/src/test/scala/firrtlTests/transforms/DedupTests.scala b/src/test/scala/firrtlTests/transforms/DedupTests.scala
index a17e6ae1..b23e9127 100644
--- a/src/test/scala/firrtlTests/transforms/DedupTests.scala
+++ b/src/test/scala/firrtlTests/transforms/DedupTests.scala
@@ -15,9 +15,10 @@ import firrtl.passes.PassExceptions
import firrtl.annotations.{
Named,
CircuitName,
+ ModuleName,
Annotation
}
-import firrtl.transforms.DedupModules
+import firrtl.transforms.{DedupModules, NoDedupAnnotation}
/**
@@ -127,6 +128,35 @@ class DedupModuleTests extends HighTransformSpec {
val aMap = new AnnotationMap(Nil)
execute(writer, aMap, input, check)
}
+ "The module B, but not A, with comments" should "be deduped if not annotated" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | x <= UInt(1)
+ | module A_ : @[xx 1:1]
+ | output x: UInt<1> @[xx 1:1]
+ | x <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | x <= UInt(1)
+ | module A_ : @[xx 1:1]
+ | output x: UInt<1> @[xx 1:1]
+ | x <= UInt(1)
+ """.stripMargin
+ val writer = new StringWriter()
+ val aMap = new AnnotationMap(Seq(NoDedupAnnotation(ModuleName("A", CircuitName("Top")))))
+ execute(writer, aMap, input, check)
+ }
}
// Execution driven tests for inlining modules