diff options
| author | Jim Lawson | 2016-12-14 17:09:51 -0800 |
|---|---|---|
| committer | GitHub | 2016-12-14 17:09:51 -0800 |
| commit | 44146d59e19fb3697a6da3c834af34a1d45160e3 (patch) | |
| tree | f1c77c9ac2bc2abe039609c5a47dc9078f7effed /src | |
| parent | 73529eda60a3e411f3270c2bf7097234a4901ab0 (diff) | |
| parent | 454d4637a45b5d70772e2831d2dc5af7864d806c (diff) | |
Merge branch 'master' into addmiddlefirrtlcompiler
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/transforms/Dedup.scala | 32 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/transforms/DedupTests.scala | 32 |
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 |
