summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
blob: 8682785b1428003e46049b67ad0bd2348df0be88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// // SPDX-License-Identifier: Apache-2.0

// package chisel3.aop.injecting

// import chisel3.{withClockAndReset, Module, ModuleAspect, RawModule}
// import chisel3.aop._
// import chisel3.internal.{Builder, DynamicContext}
// import chisel3.internal.firrtl.DefModule
// import chisel3.stage.{ChiselOptions, DesignAnnotation}
// import firrtl.annotations.ModuleTarget
// import firrtl.stage.RunFirrtlTransformAnnotation
// import firrtl.options.Viewer.view
// import firrtl.{ir, _}

// import scala.collection.mutable

// /** Aspect to inject Chisel code into a module of type M
//   *
//   * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
//   * @param injection Function to generate Chisel hardware that will be injected to the end of module m
//   *                  Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
//   * @tparam T Type of top-level module
//   * @tparam M Type of root module (join point)
//   */
// case class InjectingAspect[T <: RawModule, M <: RawModule](
//   selectRoots: T => Iterable[M],
//   injection:   M => Unit)
//     extends InjectorAspect[T, M](
//       selectRoots,
//       injection
//     )

// /** Extend to inject Chisel code into a module of type M
//   *
//   * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
//   * @param injection Function to generate Chisel hardware that will be injected to the end of module m
//   *                  Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
//   * @tparam T Type of top-level module
//   * @tparam M Type of root module (join point)
//   */
// abstract class InjectorAspect[T <: RawModule, M <: RawModule](
//   selectRoots: T => Iterable[M],
//   injection:   M => Unit)
//     extends Aspect[T] {
//   final def toAnnotation(top: T): AnnotationSeq = {
//     val moduleNames =
//       Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map { i => i.toTarget.module }.toSeq
//     toAnnotation(selectRoots(top), top.name, moduleNames)
//   }

//   /** Returns annotations which contain all injection logic
//     *
//     * @param modules The modules to inject into
//     * @param circuit Top level circuit
//     * @param moduleNames The names of all existing modules in the original circuit, to avoid name collisions
//     * @return
//     */
//   final def toAnnotation(modules: Iterable[M], circuit: String, moduleNames: Seq[String]): AnnotationSeq = {
//     RunFirrtlTransformAnnotation(new InjectingTransform) +: modules.map { module =>
//       val chiselOptions = view[ChiselOptions](annotationsInAspect)
//       val dynamicContext =
//         new DynamicContext(
//           annotationsInAspect,
//           chiselOptions.throwOnFirstError,
//           chiselOptions.warnReflectiveNaming,
//           chiselOptions.warningsAsErrors
//         )
//       // Add existing module names into the namespace. If injection logic instantiates new modules
//       //  which would share the same name, they will get uniquified accordingly
//       moduleNames.foreach { n =>
//         dynamicContext.globalNamespace.name(n)
//       }

//       val (chiselIR, _) = Builder.build(
//         Module(new ModuleAspect(module) {
//           module match {
//             case x: Module    => withClockAndReset(x.clock, x.reset) { injection(module) }
//             case x: RawModule => injection(module)
//           }
//         }),
//         dynamicContext
//       )

//       val comps = chiselIR.components.map {
//         case x: DefModule if x.name == module.name => x.copy(id = module)
//         case other => other
//       }

//       val annotations = chiselIR.annotations.map(_.toFirrtl).filterNot { a => a.isInstanceOf[DesignAnnotation[_]] }

//       /** Statements to be injected via aspect. */
//       val stmts = mutable.ArrayBuffer[ir.Statement]()

//       /** Modules to be injected via aspect. */
//       val modules = Aspect.getFirrtl(chiselIR.copy(components = comps)).modules.flatMap {
//         // for "container" modules, inject their statements
//         case m: firrtl.ir.Module if m.name == module.name =>
//           stmts += m.body
//           Nil
//         // for modules to be injected
//         case other: firrtl.ir.DefModule =>
//           Seq(other)
//       }

//       InjectStatement(ModuleTarget(circuit, module.name), ir.Block(stmts.toSeq), modules, annotations)
//     }.toSeq
//   }
// }