diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/firrtl/AddDescriptionNodes.scala | 14 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 11 | ||||
| -rw-r--r-- | src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala | 13 | ||||
| -rw-r--r-- | src/main/scala/firrtl/transforms/DedupAnnotations.scala | 4 |
4 files changed, 34 insertions, 8 deletions
diff --git a/src/main/scala/firrtl/AddDescriptionNodes.scala b/src/main/scala/firrtl/AddDescriptionNodes.scala index 123ae6e3..90e38beb 100644 --- a/src/main/scala/firrtl/AddDescriptionNodes.scala +++ b/src/main/scala/firrtl/AddDescriptionNodes.scala @@ -28,6 +28,13 @@ case class DocStringAnnotation(target: Target, description: String) extends Desc case Some(seq) => seq.map(n => this.copy(target = n)) } } + override private[firrtl] def dedup: Option[(Any, Annotation, ReferenceTarget)] = this match { + case a @ DocStringAnnotation(refTarget: ReferenceTarget, _) => + Some(((refTarget.pathlessTarget, description), copy(target = refTarget.pathlessTarget), refTarget)) + case a @ DocStringAnnotation(pathTarget: InstanceTarget, _) => + Some(((pathTarget.pathlessTarget, description), copy(target = pathTarget.pathlessTarget), pathTarget.asReference)) + case _ => None + } } /** @@ -42,6 +49,13 @@ case class AttributeAnnotation(target: Target, description: String) extends Desc case Some(seq) => seq.map(n => this.copy(target = n)) } } + override private[firrtl] def dedup: Option[(Any, Annotation, ReferenceTarget)] = this match { + case a @ AttributeAnnotation(refTarget: ReferenceTarget, _) => + Some(((refTarget.pathlessTarget, description), copy(target = refTarget.pathlessTarget), refTarget)) + case a @ AttributeAnnotation(pathTarget: InstanceTarget, _) => + Some(((pathTarget.pathlessTarget, description), copy(target = pathTarget.pathlessTarget), pathTarget.asReference)) + case _ => None + } } /** diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala index e29c1a3b..e2bb06ff 100644 --- a/src/main/scala/firrtl/Utils.scala +++ b/src/main/scala/firrtl/Utils.scala @@ -967,6 +967,17 @@ object Utils extends LazyLogging { Mux(cond, tval, fval, tval.tpe) } + /** Similar to Seq.groupBy except that it preserves ordering of elements within each group */ + def groupByIntoSeq[A, K](xs: Iterable[A])(f: A => K): Seq[(K, Seq[A])] = { + val map = mutable.LinkedHashMap.empty[K, mutable.ListBuffer[A]] + for (x <- xs) { + val key = f(x) + val l = map.getOrElseUpdate(key, mutable.ListBuffer.empty[A]) + l += x + } + map.view.map({ case (k, vs) => k -> vs.toList }).toList + } + object True { private val _True = UIntLiteral(1, IntWidth(1)) diff --git a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala index 8b20d365..4f62f27e 100644 --- a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala +++ b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala @@ -8,6 +8,7 @@ import firrtl.Utils._ import firrtl.WrappedExpression._ import firrtl.traversals.Foreachers._ import firrtl.annotations.{ + Annotation, CircuitTarget, MemoryInitAnnotation, MemoryLoadFileType, @@ -509,14 +510,14 @@ class VerilogEmitter extends SeqTransform with Emitter { case m: SingleTargetAnnotation[ReferenceTarget] @unchecked with EmissionOption => m } - // Check for non-local memory annotations (error if found) - emissionAnnos.foreach { - case a: MemoryInitAnnotation => { - if (!a.target.isLocal) + annotations.foreach { + case a: Annotation if a.dedup.nonEmpty => + val (_, _, target) = a.dedup.get + if (!target.isLocal) { throw new FirrtlUserException( - "At least one memory annotation did not deduplicate: got non-local annotation $a from [[DedupAnnotationsTransform]]" + "At least one dedupable annotation did not deduplicate: got non-local annotation $a from [[DedupAnnotationsTransform]]" ) - } + } case _ => } diff --git a/src/main/scala/firrtl/transforms/DedupAnnotations.scala b/src/main/scala/firrtl/transforms/DedupAnnotations.scala index 9355b5c3..cad4d2be 100644 --- a/src/main/scala/firrtl/transforms/DedupAnnotations.scala +++ b/src/main/scala/firrtl/transforms/DedupAnnotations.scala @@ -6,7 +6,7 @@ package transforms import firrtl.ir._ import firrtl.Mappers._ import firrtl.options.Dependency -import firrtl.Utils.BoolType +import firrtl.Utils.{groupByIntoSeq, BoolType} import firrtl.annotations.Annotation import scala.collection.mutable.Buffer import firrtl.annotations.MemoryFileInlineAnnotation @@ -61,7 +61,7 @@ object DedupAnnotationsTransform { } // Partition the dedupable annotations into groups that *should* deduplicate into the same annotation - val shouldDedup: Map[Any, ArrayBuffer[DedupableRepr]] = canDedup.groupBy(_.dedupKey) + val shouldDedup: Seq[(Any, Seq[DedupableRepr])] = groupByIntoSeq(canDedup)(_.dedupKey) shouldDedup.foreach { case ((target: ReferenceTarget, _), dedupableAnnos) => val originalAnnos = dedupableAnnos.map(_.original) |
