diff options
| author | Sequencer | 2019-07-25 21:30:11 +0000 |
|---|---|---|
| committer | mergify[bot] | 2019-07-25 21:30:11 +0000 |
| commit | 84a1c7b1f7311ce036cb7d3d5eb652466b87dce4 (patch) | |
| tree | 43dcc20d75a7b57b045032e87412dd0c8bf2d416 /src | |
| parent | 30bff5f8b627001f5ad220404e33cd087f463ed8 (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.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 |
