1
1
package chisel3 .tywavesinternal
2
2
3
- import chisel3 .{Data , Record , Vec , VecLike }
3
+ import chisel3 .{Data , MemBase , Record , Vec , VecLike }
4
4
import chisel3 .experimental .{BaseModule , ChiselAnnotation }
5
- import chisel3 .internal .HasId
5
+ import chisel3 .internal .{ HasId , NamedComponent }
6
6
import chisel3 .internal .firrtl .ir ._
7
+ import chisel3 .properties .{DynamicObject , StaticObject }
7
8
import firrtl .annotations .{Annotation , IsMember , SingleTargetAnnotation }
8
9
10
+ import scala .collection .mutable
11
+
9
12
// TODO: if the code touches a lot of Chisel internals, it might be better to put it into
10
13
// - core
11
14
// otherwise:
@@ -45,11 +48,31 @@ private[chisel3] case class TywavesAnnotation[T <: IsMember](
45
48
}
46
49
47
50
object TywavesChiselAnnotation {
51
+
52
+ private val annoCreated = new mutable.HashSet [IsMember ]()
53
+ private def createTywavesChiselAnno [T <: IsMember ](
54
+ target : T ,
55
+ name : String ,
56
+ paramsOpt : Option [Seq [ClassParam ]]
57
+ ): Option [ChiselAnnotation ] = {
58
+
59
+ if (annoCreated.contains(target)) {
60
+ None
61
+ } else {
62
+ annoCreated.add(target)
63
+ Some (new ChiselAnnotation {
64
+ override def toFirrtl : Annotation = TywavesAnnotation (target, name, paramsOpt)
65
+ })
66
+ }
67
+ }
68
+
48
69
def generate (circuit : Circuit ): Seq [ChiselAnnotation ] = {
49
70
// TODO: iterate over a circuit and generate TywavesAnnotation
50
71
val typeAliases : Seq [String ] = circuit.typeAliases.map(_.name)
51
72
52
- circuit.components.flatMap(c => generate(c, typeAliases))
73
+ val result = circuit.components.flatMap(c => generate(c, typeAliases))
74
+ annoCreated.clear()
75
+ result
53
76
// circuit.layers
54
77
// circuit.options
55
78
@@ -59,18 +82,18 @@ object TywavesChiselAnnotation {
59
82
def generate (component : Component , typeAliases : Seq [String ]): Seq [ChiselAnnotation ] = component match {
60
83
case ctx @ DefModule (id, name, public, layers, ports, cmds) =>
61
84
// TODO: Add tywaves annotation: components, ports, commands, layers
62
- Seq ( createAnno(id) ) ++ (ports ++ ctx.secretPorts).flatMap(p =>
85
+ createAnno(id) ++ (ports ++ ctx.secretPorts).flatMap(p =>
63
86
generate(p, typeAliases)
64
87
) ++ (cmds ++ ctx.secretCommands).flatMap(c => generate(c, typeAliases))
65
88
case ctx @ DefBlackBox (id, name, ports, topDir, params) =>
66
89
// TODO: Add tywaves annotation, ports, ?params?
67
- Seq ( createAnno(id) ) ++ (ports ++ ctx.secretPorts).flatMap(p => generate(p, typeAliases))
90
+ createAnno(id) ++ (ports ++ ctx.secretPorts).flatMap(p => generate(p, typeAliases))
68
91
case ctx @ DefIntrinsicModule (id, name, ports, topDir, params) =>
69
92
// TODO: Add tywaves annotation: ports, ?params?
70
- Seq ( createAnno(id) ) ++ (ports ++ ctx.secretPorts).flatMap(p => generate(p, typeAliases))
93
+ createAnno(id) ++ (ports ++ ctx.secretPorts).flatMap(p => generate(p, typeAliases))
71
94
case ctx @ DefClass (id, name, ports, cmds) =>
72
95
// TODO: Add tywaves annotation: ports, commands
73
- Seq ( createAnno(id) ) ++ (ports ++ ctx.secretPorts).flatMap(p => generate(p, typeAliases)) ++ cmds.flatMap(c =>
96
+ createAnno(id) ++ (ports ++ ctx.secretPorts).flatMap(p => generate(p, typeAliases)) ++ cmds.flatMap(c =>
74
97
generate(c, typeAliases)
75
98
)
76
99
case ctx => throw new Exception (s " Failed to generate TywavesAnnotation. Unknown component type: $ctx" )
@@ -84,9 +107,10 @@ object TywavesChiselAnnotation {
84
107
val name = s " $binding[ ${dataToTypeName(innerType)}[ $size]] "
85
108
// TODO: what if innerType is a Vec or a Bundle?
86
109
87
- Seq (new ChiselAnnotation {
88
- override def toFirrtl : Annotation = TywavesAnnotation (target.toTarget, name, None )
89
- }) // ++ createAnno(chisel3.Wire(innerType))
110
+ createTywavesChiselAnno(target.toTarget, name, None ).toSeq
111
+ // Seq(new ChiselAnnotation {
112
+ // override def toFirrtl: Annotation = TywavesAnnotation(target.toTarget, name, None)
113
+ // }) //++ createAnno(chisel3.Wire(innerType))
90
114
}
91
115
command match {
92
116
case e : DefPrim [_] => Seq .empty // TODO: check prim
@@ -98,7 +122,7 @@ object TywavesChiselAnnotation {
98
122
case e @ FirrtlMemory (info, id, t, size, readPortNames, writePortNames, readwritePortNames) =>
99
123
createAnnoMem(id, id.getClass.getSimpleName, size, t)
100
124
case e @ DefMemPort (info, id, source, dir, idx, clock) => createAnno(id)
101
- case Connect (info, loc, exp) => Seq .empty // TODO: check connect
125
+ case Connect (info, loc, exp) => createAnno(exp)
102
126
case PropAssign (info, loc, exp) => ???
103
127
case Attach (info, locs) => ???
104
128
case DefInvalid (info, arg) => Seq .empty // TODO: check invalid
@@ -113,6 +137,11 @@ object TywavesChiselAnnotation {
113
137
case e @ ProbeForce (sourceInfo, clock, cond, probe, value) => ???
114
138
case e @ ProbeRelease (sourceInfo, clock, cond, probe) => ???
115
139
case e @ Verification (_, op, info, clk, pred, pable) => ???
140
+ case e @ When (info, arg, ifRegion, elseRegion) =>
141
+ println(s " $ifRegion" )
142
+ println(s " $elseRegion" )
143
+ ifRegion.flatMap(generate(_, typeAliases)) ++ elseRegion
144
+ .flatMap(generate(_, typeAliases))
116
145
case e =>
117
146
println(s " Unknown command: $e" ) // TODO: replace with logger
118
147
Seq .empty
@@ -316,18 +345,59 @@ object TywavesChiselAnnotation {
316
345
case _ => getConstructorParamsOpt(target)
317
346
}
318
347
319
- annotations :+ new ChiselAnnotation {
320
- override def toFirrtl : Annotation = TywavesAnnotation (target.toTarget, name, paramsOpt)
321
- }
348
+ annotations ++
349
+ createTywavesChiselAnno(target.toTarget, name, paramsOpt).toSeq
350
+ // new ChiselAnnotation {
351
+ // override def toFirrtl: Annotation = TywavesAnnotation(target.toTarget, name, paramsOpt)
352
+ // }
322
353
}
323
354
324
- private def createAnno (target : BaseModule ): ChiselAnnotation = {
355
+ private def createAnno (target : BaseModule ): Seq [ ChiselAnnotation ] = {
325
356
val name = target.desiredName
326
357
val paramsOpt = getConstructorParamsOpt(target)
327
358
// val name = target.getClass.getTypeName
328
- new ChiselAnnotation {
329
- override def toFirrtl : Annotation = TywavesAnnotation (target.toTarget, name, paramsOpt)
359
+ createTywavesChiselAnno(target.toTarget, name, paramsOpt).toSeq
360
+
361
+ // new ChiselAnnotation {
362
+ // override def toFirrtl: Annotation = TywavesAnnotation(target.toTarget, name, paramsOpt)
363
+ // }
364
+ }
365
+
366
+ // TODO: replace ??? with a nice logger to avoid unexpected crashes
367
+ private def createAnno (target : HasId ): Seq [ChiselAnnotation ] = {
368
+ target match {
369
+ case t : Data => createAnno(t)
370
+ case t : BaseModule => createAnno(t)
371
+ case t : MemBase [_] => ???
372
+ case t : NamedComponent => ???
373
+ case t : VecLike [_] => ???
374
+ case t if t.isInstanceOf [DynamicObject ] => ???
375
+ case t if t.isInstanceOf [StaticObject ] => ???
376
+ }
377
+ }
378
+ // TODO: check all the cases for Arg
379
+ private def createAnno (target : Arg ): Seq [ChiselAnnotation ] = {
380
+ target match {
381
+ case t @ Node (id) => createAnno(id)
382
+ case t @ ModuleIO (mod, name) => ???
383
+ case t @ ILit (n) => ???
384
+ case t @ Ref (name) => ???
385
+ case t @ PropertyLit (propertyType, lit) => ???
386
+ case t @ PropExpr (sourceInfo, tpe, op, args) => ???
387
+ case t @ Slot (imm, name) => ???
388
+ case t @ ProbeExpr (probe) => ???
389
+ case t @ ProbeRead (probe) => ???
390
+ case t @ RWProbeExpr (probe) => ???
391
+ case t @ Index (imm, value) => ???
392
+ case t @ ModuleCloneIO (mod, name) => ???
393
+ case t @ OpaqueSlot (imm) => ???
394
+ case t : Component => ???
395
+ case t : LitArg => Seq .empty // Ignore
396
+ case t =>
397
+ println(s " Unknown Arg type: $t" )
398
+ Seq .empty
330
399
}
400
+
331
401
}
332
402
333
403
}
0 commit comments