diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/annotations/Annotation.scala | 39 |
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 |
