aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSequencer2019-07-25 21:30:11 +0000
committermergify[bot]2019-07-25 21:30:11 +0000
commit84a1c7b1f7311ce036cb7d3d5eb652466b87dce4 (patch)
tree43dcc20d75a7b57b045032e87412dd0c8bf2d416 /src
parent30bff5f8b627001f5ad220404e33cd087f463ed8 (diff)
Implement MultiTargetAnnotation (#1109)
* add multi target annotation for advices * use Seq[Seq[Target]] store targets * add flat function * doc simplify
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/annotations/Annotation.scala39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/annotations/Annotation.scala b/src/main/scala/firrtl/annotations/Annotation.scala
index 8aba4826..adde816a 100644
--- a/src/main/scala/firrtl/annotations/Annotation.scala
+++ b/src/main/scala/firrtl/annotations/Annotation.scala
@@ -77,6 +77,45 @@ trait SingleTargetAnnotation[T <: Named] extends Annotation {
}
}
+/** [[MultiTargetAnnotation]] keeps the renamed targets grouped within a single annotation. */
+trait MultiTargetAnnotation extends Annotation {
+ /** Contains a sequence of [[Target]].
+ * When creating in [[toFirrtl]], [[targets]] should be assigned by `Seq(Seq(TargetA), Seq(TargetB), Seq(TargetC))`
+ * */
+ val targets: Seq[Seq[Target]]
+
+ /** Create another instance of this Annotation*/
+ def duplicate(n: Seq[Seq[Target]]): Annotation
+
+ /** Assume [[RenameMap]] is `Map(TargetA -> Seq(TargetA1, TargetA2, TargetA3), TargetB -> Seq(TargetB1, TargetB2))`
+ * in the update, this Annotation is still one annotation, but the contents are renamed in the below form
+ * Seq(Seq(TargetA1, TargetA2, TargetA3), Seq(TargetB1, TargetB2), Seq(TargetC))
+ **/
+ def update(renames: RenameMap): Seq[Annotation] = Seq(duplicate(targets.map(ts => ts.flatMap(renames(_)))))
+
+ private def crossJoin[T](list: Seq[Seq[T]]): Seq[Seq[T]] =
+ list match {
+ case Nil => Nil
+ case x :: Nil => x map (Seq(_))
+ case x :: xs =>
+ val xsJoin = crossJoin(xs)
+ for {
+ i <- x
+ j <- xsJoin
+ } yield {
+ Seq(i) ++ j
+ }
+ }
+
+ /** Assume [[RenameMap]] is `Map(TargetA -> Seq(TargetA1, TargetA2, TargetA3), TargetB -> Seq(TargetB1, TargetB2))`
+ * After flat, this Annotation will be flat to the [[AnnotationSeq]] in the below form
+ * Seq(Seq(TargetA1), Seq(TargetB1), Seq(TargetC)); Seq(Seq(TargetA1), Seq(TargetB2), Seq(TargetC))
+ * Seq(Seq(TargetA2), Seq(TargetB1), Seq(TargetC)); Seq(Seq(TargetA2), Seq(TargetB2), Seq(TargetC))
+ * Seq(Seq(TargetA3), Seq(TargetB1), Seq(TargetC)); Seq(Seq(TargetA3), Seq(TargetB2), Seq(TargetC))
+ * */
+ def flat(): AnnotationSeq = crossJoin(targets).map(r => duplicate(r.map(Seq(_))))
+}
+
@deprecated("Just extend NoTargetAnnotation", "1.1")
trait SingleStringAnnotation extends NoTargetAnnotation {
def value: String