Skip to content

Commit 9d28ac6

Browse files
Refine annotate and Targetable (backport #4698) (#4703)
* Refine annotate and Targetable (#4698) Some minor improvements to the user API for annotating with Targetable * Support annotating Seq[Targetable] and provide Targetable for AnyTargetable. * Add AnyTargetable.apply for simpler manual conversions. * Show tests annotating Seq[Targetable] and manual use of AnyTargetable. (cherry picked from commit e20069e) * Run formatting --------- Co-authored-by: Jack Koenig <[email protected]>
1 parent 55dd49d commit 9d28ac6

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

core/src/main/scala/chisel3/Annotation.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ object annotate {
6969
def toFirrtl: Seq[Annotation] = mkAnnos
7070
}
7171
}
72+
73+
/** Create annotations.
74+
*
75+
* Avoid this API if possible.
76+
*
77+
* Anything being annotated must be passed as arguments so that Chisel can do safety checks.
78+
* The caller is still responsible for calling .toTarget on those arguments in mkAnnos.
79+
*/
80+
def apply[T: Targetable](targets: Seq[T])(mkAnnos: => Seq[Annotation]): Unit = {
81+
annotate(targets.map(t => AnyTargetable.toAnyTargetable(t)): _*)(mkAnnos)
82+
}
7283
}
7384

7485
/** Marks that a module to be ignored in Dedup Transform in Firrtl pass

core/src/main/scala/chisel3/experimental/Targetable.scala

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ object Targetable {
9595
def toRelativeTargetToHierarchy(a: HasTarget, root: Option[Hierarchy[BaseModule]]): IsMember =
9696
a.toRelativeTargetToHierarchy(root)
9797
}
98+
99+
implicit def forAnyTargetable: Targetable[AnyTargetable] = new Targetable[AnyTargetable] {
100+
def toTarget(a: AnyTargetable): IsMember = a.toTarget
101+
def toAbsoluteTarget(a: AnyTargetable): IsMember = a.toAbsoluteTarget
102+
def toRelativeTarget(a: AnyTargetable, root: Option[BaseModule]): IsMember = a.toRelativeTarget(root)
103+
def toRelativeTargetToHierarchy(a: AnyTargetable, root: Option[Hierarchy[BaseModule]]): IsMember =
104+
a.toRelativeTargetToHierarchy(root)
105+
}
98106
}
99107

100108
/** Existential Type class for types that can be converted to a Target
@@ -116,8 +124,11 @@ sealed trait AnyTargetable {
116124

117125
object AnyTargetable {
118126

119-
/** Implicit conversion making working with Targetables easier */
120-
implicit def toAnyTargetable[A](a: A)(implicit targetable: Targetable[A]): AnyTargetable = {
127+
/** Convert any Targetable A to an AnyTargetable
128+
*
129+
* This effectively erases the type parameter and allows mixing of different concrete Targetable objects.
130+
*/
131+
def apply[A](a: A)(implicit targetable: Targetable[A]): AnyTargetable = {
121132
type _A = A
122133
val _a = a
123134
val _targetable = targetable
@@ -127,4 +138,7 @@ object AnyTargetable {
127138
val targetable: Targetable[A] = _targetable
128139
}
129140
}
141+
142+
/** Implicit conversion making working with Targetables easier */
143+
implicit def toAnyTargetable[A: Targetable](a: A): AnyTargetable = apply(a)
130144
}

src/test/scala/chiselTests/NewAnnotationsSpec.scala

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
13
package chiselTests
4+
5+
import circt.stage.ChiselStage
6+
27
import chisel3._
3-
import chisel3.experimental.annotate
8+
import chisel3.experimental.{annotate, AnyTargetable}
49
import chisel3.stage.ChiselGeneratorAnnotation
5-
import circt.stage.ChiselStage
6-
import firrtl.stage.FirrtlCircuitAnnotation
10+
import chiselTests.experimental.hierarchy.Utils
11+
12+
import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation}
13+
714
import org.scalatest.freespec.AnyFreeSpec
815
import org.scalatest.matchers.should.Matchers
9-
import firrtl.transforms.NoDedupAnnotation
10-
import firrtl.transforms.DontTouchAnnotation
1116

12-
class NewAnnotationsSpec extends AnyFreeSpec with Matchers {
17+
class NewAnnotationsSpec extends AnyFreeSpec with Matchers with ChiselRunners with Utils {
1318

1419
class MuchUsedModule extends Module {
1520
val io = IO(new Bundle {
@@ -41,9 +46,10 @@ class NewAnnotationsSpec extends AnyFreeSpec with Matchers {
4146
annotate(mod3)(Seq(new NoDedupAnnotation(mod3.toNamed)))
4247

4348
// Pass multiple annotations in the same seq - should get emitted out correctly.
44-
annotate(mod1.io.in, mod1.io.out)(
45-
Seq(new DontTouchAnnotation(mod1.io.in.toNamed), new DontTouchAnnotation(mod1.io.out.toNamed))
46-
)
49+
val ports = Seq(mod1.io.in, mod1.io.out)
50+
annotate(ports)({
51+
ports.map(p => new DontTouchAnnotation(p.toTarget))
52+
})
4753
}
4854

4955
val stage = new ChiselStage
@@ -66,7 +72,30 @@ class NewAnnotationsSpec extends AnyFreeSpec with Matchers {
6672
noDedupAnnosCombined should include("~UsesMuchUsedModule|MuchUsedModule_3")
6773
dontTouchAnnosCombined should include("~UsesMuchUsedModule|MuchUsedModule_1>io.out")
6874
dontTouchAnnosCombined should include("~UsesMuchUsedModule|MuchUsedModule_1>io.in")
75+
}
6976

77+
"It should be possible to annotate heterogeneous Targetable things" in {
78+
val (_, annotations) = getFirrtlAndAnnos(new RawModule {
79+
override def desiredName: String = "Top"
80+
val in = IO(Input(UInt(8.W)))
81+
val out = IO(Output(UInt(8.W)))
82+
out := in
83+
// Given a Seq[UInt]
84+
val xs: Seq[UInt] = Seq(in, out)
85+
// We can manually use AnyTargetable to also include a Module
86+
// Using either type ascriptions to invoke the implicit conversion, or manually
87+
val ys = Seq[AnyTargetable](this) ++ xs.map(AnyTargetable(_))
88+
annotate(ys)(
89+
Seq(
90+
DontTouchAnnotation(in.toTarget),
91+
DontTouchAnnotation(out.toTarget),
92+
NoDedupAnnotation(this.toNamed)
93+
)
94+
)
95+
})
96+
annotations should contain(DontTouchAnnotation("~Top|Top>in".rt))
97+
annotations should contain(DontTouchAnnotation("~Top|Top>out".rt))
98+
annotations should contain(NoDedupAnnotation("~Top|Top".mt))
7099
}
71100
}
72101
}

0 commit comments

Comments
 (0)