summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/aop
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/chisel3/aop')
-rw-r--r--src/main/scala/chisel3/aop/AspectLibrary.scala53
-rw-r--r--src/main/scala/chisel3/aop/Select.scala614
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectStatement.scala26
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala108
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingTransform.scala46
-rw-r--r--src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala26
6 files changed, 0 insertions, 873 deletions
diff --git a/src/main/scala/chisel3/aop/AspectLibrary.scala b/src/main/scala/chisel3/aop/AspectLibrary.scala
deleted file mode 100644
index 04ac2384..00000000
--- a/src/main/scala/chisel3/aop/AspectLibrary.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3.RawModule
-import firrtl.options.{OptionsException, RegisteredLibrary, ShellOption}
-
-/** Enables adding aspects to a design from the commandline, e.g.
- * sbt> runMain chisel3.stage.ChiselMain --module <module> --with-aspect <aspect>
- */
-final class AspectLibrary() extends RegisteredLibrary {
- val name = "AspectLibrary"
-
- import scala.reflect.runtime.universe._
-
- private def apply(aspectName: String): Aspect[RawModule] = {
- try {
- // If a regular class, instantiate, otherwise try as a singleton object
- try {
- val x = Class.forName(aspectName).asInstanceOf[Class[_ <: Aspect[RawModule]]]
- x.newInstance()
- } catch {
- case e: InstantiationException =>
- val rm = runtimeMirror(getClass.getClassLoader)
- val x = rm.staticModule(aspectName)
- try {
- rm.reflectModule(x).instance.asInstanceOf[Aspect[RawModule]]
- } catch {
- case _: Exception => throw e
- }
- }
- } catch {
- case e: ClassNotFoundException =>
- throw new OptionsException(s"Unable to locate aspect '$aspectName'! (Did you misspell it?)", e)
- case e: InstantiationException =>
- throw new OptionsException(
- s"Unable to create instance of aspect '$aspectName'! (Does this class take parameters?)",
- e
- )
- }
- }
-
- val options = Seq(
- new ShellOption[String](
- longOption = "with-aspect",
- toAnnotationSeq = {
- case aspectName: String => Seq(apply(aspectName))
- },
- helpText = "The name/class of an aspect to compile with (must be a class/object without arguments!)",
- helpValueName = Some("<package>.<aspect>")
- )
- )
-}
diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala
deleted file mode 100644
index 738d6f31..00000000
--- a/src/main/scala/chisel3/aop/Select.scala
+++ /dev/null
@@ -1,614 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3._
-import chisel3.internal.{HasId}
-import chisel3.experimental.BaseModule
-import chisel3.experimental.FixedPoint
-import chisel3.internal.firrtl.{Definition => DefinitionIR, _}
-import chisel3.experimental.hierarchy._
-import chisel3.internal.PseudoModule
-import chisel3.internal.BaseModule.ModuleClone
-import firrtl.annotations.ReferenceTarget
-import scala.reflect.runtime.universe.TypeTag
-
-import scala.collection.mutable
-import chisel3.internal.naming.chiselName
-
-/** Use to select Chisel components in a module, after that module has been constructed
- * Useful for adding additional Chisel annotations or for use within an [[Aspect]]
- */
-object Select {
-
- /** Return just leaf components of expanded node
- *
- * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies are not included
- */
- def getLeafs(d: Data): Seq[Data] = d match {
- case r: Record => r.elementsIterator.flatMap(getLeafs).toSeq
- case v: Vec[_] => v.getElements.flatMap(getLeafs)
- case other => Seq(other)
- }
-
- /** Return all expanded components, including intermediate aggregate nodes
- *
- * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies ARE included
- */
- def getIntermediateAndLeafs(d: Data): Seq[Data] = d match {
- case r: Record => r +: r.elementsIterator.flatMap(getIntermediateAndLeafs).toSeq
- case v: Vec[_] => v +: v.getElements.flatMap(getIntermediateAndLeafs)
- case other => Seq(other)
- }
-
- /** Selects all instances/modules directly instantiated within given definition
- *
- * @param parent
- */
- def instancesIn(parent: Hierarchy[BaseModule]): Seq[Instance[BaseModule]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent.proto._component.get match {
- case d: DefModule =>
- d.commands.collect {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
- case other: BaseModule =>
- parent._lookup { x => other }
- }
- }
- case other => Nil
- }
- }
-
- /** Selects all Instances of instances/modules directly instantiated within given module, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. instancesOf[List[Int]] would return List[String].
- *
- * @param parent hierarchy which instantiates the returned Definitions
- */
- def instancesOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent.proto._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
- if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
- case other: BaseModule =>
- val i = parent._lookup { x => other }
- if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
- }
- case other => None
- }
- case other => Nil
- }
- }
-
- /** Selects all Instances directly and indirectly instantiated within given root hierarchy, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. allInstancesOf[List[Int]] would return List[String].
- *
- * @param root top of the hierarchy to search for instances/modules of given type
- */
- def allInstancesOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = {
- val soFar = if (root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil
- val allLocalInstances = instancesIn(root)
- soFar ++ (allLocalInstances.flatMap(allInstancesOf[T]))
- }
-
- /** Selects the Definitions of all instances/modules directly instantiated within given module
- *
- * @param parent
- */
- def definitionsIn(parent: Hierarchy[BaseModule]): Seq[Definition[BaseModule]] = {
- type DefType = Definition[BaseModule]
- implicit val mg = new chisel3.internal.MacroGenerated {}
- check(parent)
- val defs = parent.proto._component.get match {
- case d: DefModule =>
- d.commands.collect {
- case i: DefInstance =>
- i.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] }
- case other: BaseModule =>
- parent._lookup { x => other.toDefinition }
- }
- }
- case other => Nil
- }
- val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
- case ((set, list), definition: Definition[BaseModule]) =>
- if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
- }
- defList.reverse
- }
-
- /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. definitionsOf[List[Int]] would return List[String].
- *
- * @param parent hierarchy which instantiates the returned Definitions
- */
- def definitionsOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- type DefType = Definition[T]
- val defs = parent.proto._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] }
- if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
- case other: BaseModule =>
- val d = parent._lookup { x => other.toDefinition }
- if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
- }
- case other => None
- }
- }
- val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
- case ((set, list), definition: Definition[T]) =>
- if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
- }
- defList.reverse
- }
-
- /** Selects all Definition's directly and indirectly instantiated within given root hierarchy, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class, i.e.
- * a class defined within another class.
- * @note IMPORTANT: this function ignores type parameters. E.g. allDefinitionsOf[List[Int]] would return List[String].
- *
- * @param root top of the hierarchy to search for definitions of given type
- */
- def allDefinitionsOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = {
- type DefType = Definition[T]
- val allDefSet = mutable.HashSet[Definition[BaseModule]]()
- val defSet = mutable.HashSet[DefType]()
- val defList = mutable.ArrayBuffer[DefType]()
- def rec(hier: Definition[BaseModule]): Unit = {
- if (hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) {
- defSet += hier.asInstanceOf[DefType]
- defList += hier.asInstanceOf[DefType]
- }
- allDefSet += hier
- val allDefs = definitionsIn(hier)
- allDefs.collect {
- case d if !allDefSet.contains(d) => rec(d)
- }
- }
- rec(root.toDefinition)
- defList.toList
- }
-
- /** Collects all components selected by collector within module and all children modules it instantiates
- * directly or indirectly
- * Accepts a collector function, rather than a collector partial function (see [[collectDeep]])
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
- *
- * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
- * @param collector Collector function to pick, given a module, which components to collect
- * @param tag Required for generics to work, should ignore this
- * @tparam T Type of the component that will be collected
- */
- def getDeep[T](module: BaseModule)(collector: BaseModule => Seq[T]): Seq[T] = {
- check(module)
- val myItems = collector(module)
- val deepChildrenItems = instances(module).flatMap { i =>
- getDeep(i)(collector)
- }
- myItems ++ deepChildrenItems
- }
-
- /** Collects all components selected by collector within module and all children modules it instantiates
- * directly or indirectly
- * Accepts a collector partial function, rather than a collector function (see [[getDeep]])
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
- *
- * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
- * @param collector Collector partial function to pick, given a module, which components to collect
- * @param tag Required for generics to work, should ignore this
- * @tparam T Type of the component that will be collected
- */
- def collectDeep[T](module: BaseModule)(collector: PartialFunction[BaseModule, T]): Iterable[T] = {
- check(module)
- val myItems = collector.lift(module)
- val deepChildrenItems = instances(module).flatMap { i =>
- collectDeep(i)(collector)
- }
- myItems ++ deepChildrenItems
- }
-
- /** Selects all modules directly instantiated within given module
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use instancesIn or definitionsIn.
- *
- * @param module
- */
- def instances(module: BaseModule): Seq[BaseModule] = {
- check(module)
- module._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case i: DefInstance =>
- i.id match {
- case m: ModuleClone[_] if !m._madeFromDefinition => None
- case _: PseudoModule =>
- throw new Exception(
- "instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!"
- )
- case other => Some(other)
- }
- case _ => None
- }
- case other => Nil
- }
- }
-
- /** Selects all registers directly instantiated within given module
- * @param module
- */
- def registers(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefReg => r.id
- case r: DefRegInit => r.id
- }
- }
-
- /** Selects all ios on a given module
- * @param module
- */
- def ios(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].ports.map(_.id)
- }
-
- /** Selects all ios directly on a given Instance or Definition of a module
- * @param parent the Definition or Instance to get the IOs of
- */
- def ios[T <: BaseModule](parent: Hierarchy[T]): Seq[Data] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent._lookup { x => ios(parent.proto) }
- }
-
- /** Selects all SyncReadMems directly contained within given module
- * @param module
- */
- def syncReadMems(module: BaseModule): Seq[SyncReadMem[_]] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefSeqMemory => r.id.asInstanceOf[SyncReadMem[_]]
- }
- }
-
- /** Selects all Mems directly contained within given module
- * @param module
- */
- def mems(module: BaseModule): Seq[Mem[_]] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemory => r.id.asInstanceOf[Mem[_]]
- }
- }
-
- /** Selects all arithmetic or logical operators directly instantiated within given module
- * @param module
- */
- def ops(module: BaseModule): Seq[(String, Data)] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case d: DefPrim[_] => (d.op.name, d.id)
- }
- }
-
- /** Selects a kind of arithmetic or logical operator directly instantiated within given module
- * The kind of operators are contained in [[chisel3.internal.firrtl.PrimOp]]
- * @param opKind the kind of operator, e.g. "mux", "add", or "bits"
- * @param module
- */
- def ops(opKind: String)(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case d: DefPrim[_] if d.op.name == opKind => d.id
- }
- }
-
- /** Selects all wires in a module
- * @param module
- */
- def wires(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefWire => r.id
- }
- }
-
- /** Selects all memory ports, including their direction and memory
- * @param module
- */
- def memPorts(module: BaseModule): Seq[(Data, MemPortDirection, MemBase[_])] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemPort[_] => (r.id, r.dir, r.source.id.asInstanceOf[MemBase[_ <: Data]])
- }
- }
-
- /** Selects all memory ports of a given direction, including their memory
- * @param dir The direction of memory ports to select
- * @param module
- */
- def memPorts(dir: MemPortDirection)(module: BaseModule): Seq[(Data, MemBase[_])] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemPort[_] if r.dir == dir => (r.id, r.source.id.asInstanceOf[MemBase[_ <: Data]])
- }
- }
-
- /** Selects all components who have been set to be invalid, even if they are later connected to
- * @param module
- */
- def invalids(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case DefInvalid(_, arg) => getData(arg)
- }
- }
-
- /** Selects all components who are attached to a given signal, within a module
- * @param module
- */
- def attachedTo(module: BaseModule)(signal: Data): Set[Data] = {
- check(module)
- module._component.get
- .asInstanceOf[DefModule]
- .commands
- .collect {
- case Attach(_, seq) if seq.contains(signal) => seq
- }
- .flatMap { seq => seq.map(_.id.asInstanceOf[Data]) }
- .toSet
- }
-
- /** Selects all connections to a signal or its parent signal(s) (if the signal is an element of an aggregate signal)
- * The when predicates surrounding each connection are included in the returned values
- *
- * E.g. if signal = io.foo.bar, connectionsTo will return all connections to io, io.foo, and io.bar
- * @param module
- * @param signal
- */
- def connectionsTo(module: BaseModule)(signal: Data): Seq[PredicatedConnect] = {
- check(module)
- val sensitivitySignals = getIntermediateAndLeafs(signal).toSet
- val predicatedConnects = mutable.ArrayBuffer[PredicatedConnect]()
- val isPort = module._component.get
- .asInstanceOf[DefModule]
- .ports
- .flatMap { p => getIntermediateAndLeafs(p.id) }
- .contains(signal)
- var prePredicates: Seq[Predicate] = Nil
- var seenDef = isPort
- searchWhens(
- module,
- (cmd: Command, preds) => {
- cmd match {
- case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] =>
- val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data])
- if (x.contains(signal)) prePredicates = preds
- case Connect(_, loc @ Node(d: Data), exp) =>
- val effected = getEffected(loc).toSet
- if (sensitivitySignals.intersect(effected).nonEmpty) {
- val expData = getData(exp)
- prePredicates.reverse
- .zip(preds.reverse)
- .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
- predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = false)
- }
- case BulkConnect(_, loc @ Node(d: Data), exp) =>
- val effected = getEffected(loc).toSet
- if (sensitivitySignals.intersect(effected).nonEmpty) {
- val expData = getData(exp)
- prePredicates.reverse
- .zip(preds.reverse)
- .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
- predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = true)
- }
- case other =>
- }
- }
- )
- predicatedConnects.toSeq
- }
-
- /** Selects all stop statements, and includes the predicates surrounding the stop statement
- *
- * @param module
- */
- def stops(module: BaseModule): Seq[Stop] = {
- val stops = mutable.ArrayBuffer[Stop]()
- searchWhens(
- module,
- (cmd: Command, preds: Seq[Predicate]) => {
- cmd match {
- case chisel3.internal.firrtl.Stop(_, _, clock, ret) =>
- stops += Stop(preds, ret, getId(clock).asInstanceOf[Clock])
- case other =>
- }
- }
- )
- stops.toSeq
- }
-
- /** Selects all printf statements, and includes the predicates surrounding the printf statement
- *
- * @param module
- */
- def printfs(module: BaseModule): Seq[Printf] = {
- val printfs = mutable.ArrayBuffer[Printf]()
- searchWhens(
- module,
- (cmd: Command, preds: Seq[Predicate]) => {
- cmd match {
- case chisel3.internal.firrtl.Printf(id, _, clock, pable) =>
- printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock])
- case other =>
- }
- }
- )
- printfs.toSeq
- }
-
- // Checks that a module has finished its construction
- private def check(module: BaseModule): Unit = {
- require(module.isClosed, "Can't use Selector on modules that have not finished construction!")
- require(module._component.isDefined, "Can't use Selector on modules that don't have components!")
- }
- private def check(hierarchy: Hierarchy[BaseModule]): Unit = check(hierarchy.proto)
-
- // Given a loc, return all subcomponents of id that could be assigned to in connect
- private def getEffected(a: Arg): Seq[Data] = a match {
- case Node(id: Data) => getIntermediateAndLeafs(id)
- case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name))
- case Index(imm, value) => getEffected(imm)
- }
-
- // Given an arg, return the corresponding id. Don't use on a loc of a connect.
- private def getId(a: Arg): HasId = a match {
- case Node(id) => id
- case l: ULit => l.num.U(l.w)
- case l: SLit => l.num.S(l.w)
- case l: FPLit => FixedPoint(l.num, l.w, l.binaryPoint)
- case other =>
- sys.error(s"Something went horribly wrong! I was expecting ${other} to be a lit or a node!")
- }
-
- private def getData(a: Arg): Data = a match {
- case Node(data: Data) => data
- case other =>
- sys.error(s"Something went horribly wrong! I was expecting ${other} to be Data!")
- }
-
- // Given an id, either get its name or its value, if its a lit
- private def getName(i: HasId): String = try {
- i.toTarget match {
- case r: ReferenceTarget =>
- val str = r.serialize
- str.splitAt(str.indexOf('>'))._2.drop(1)
- }
- } catch {
- case e: ChiselException =>
- i.getOptionRef.get match {
- case l: LitArg => l.num.intValue.toString
- }
- }
-
- // Collects when predicates as it searches through a module, then applying processCommand to non-when related commands
- private def searchWhens(module: BaseModule, processCommand: (Command, Seq[Predicate]) => Unit) = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.foldLeft((Seq.empty[Predicate], Option.empty[Predicate])) {
- (blah, cmd) =>
- (blah, cmd) match {
- case ((preds, o), cmd) =>
- cmd match {
- case WhenBegin(_, Node(pred: Bool)) => (When(pred) +: preds, None)
- case WhenBegin(_, l: LitArg) if l.num == BigInt(1) => (When(true.B) +: preds, None)
- case WhenBegin(_, l: LitArg) if l.num == BigInt(0) => (When(false.B) +: preds, None)
- case other: WhenBegin =>
- sys.error(s"Something went horribly wrong! I was expecting ${other.pred} to be a lit or a bool!")
- case _: WhenEnd => (preds.tail, Some(preds.head))
- case AltBegin(_) if o.isDefined => (o.get.not +: preds, o)
- case _: AltBegin =>
- sys.error(s"Something went horribly wrong! I was expecting ${o} to be nonEmpty!")
- case OtherwiseEnd(_, _) => (preds.tail, None)
- case other =>
- processCommand(cmd, preds)
- (preds, o)
- }
- }
- }
- }
-
- trait Serializeable {
- def serialize: String
- }
-
- /** Used to indicates a when's predicate (or its otherwise predicate)
- */
- trait Predicate extends Serializeable {
- val bool: Bool
- def not: Predicate
- }
-
- /** Used to represent [[chisel3.when]] predicate
- *
- * @param bool the when predicate
- */
- case class When(bool: Bool) extends Predicate {
- def not: WhenNot = WhenNot(bool)
- def serialize: String = s"${getName(bool)}"
- }
-
- /** Used to represent the `otherwise` predicate of a [[chisel3.when]]
- *
- * @param bool the when predicate corresponding to this otherwise predicate
- */
- case class WhenNot(bool: Bool) extends Predicate {
- def not: When = When(bool)
- def serialize: String = s"!${getName(bool)}"
- }
-
- /** Used to represent a connection or bulk connection
- *
- * Additionally contains the sequence of when predicates seen when the connection is declared
- *
- * @param preds
- * @param loc
- * @param exp
- * @param isBulk
- */
- case class PredicatedConnect(preds: Seq[Predicate], loc: Data, exp: Data, isBulk: Boolean) extends Serializeable {
- def serialize: String = {
- val moduleTarget = loc.toTarget.moduleTarget.serialize
- s"$moduleTarget: when(${preds.map(_.serialize).mkString(" & ")}): ${getName(loc)} ${if (isBulk) "<>" else ":="} ${getName(exp)}"
- }
- }
-
- /** Used to represent a [[chisel3.stop]]
- *
- * @param preds
- * @param ret
- * @param clock
- */
- case class Stop(preds: Seq[Predicate], ret: Int, clock: Clock) extends Serializeable {
- def serialize: String = {
- s"stop when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $ret"
- }
- }
-
- /** Used to represent a [[chisel3.printf]]
- *
- * @param preds
- * @param pable
- * @param clock
- */
- case class Printf(id: printf.Printf, preds: Seq[Predicate], pable: Printable, clock: Clock) extends Serializeable {
- def serialize: String = {
- s"printf when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $pable"
- }
- }
-}
diff --git a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala b/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
deleted file mode 100644
index dbe1fd7b..00000000
--- a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.injecting
-
-import chisel3.stage.phases.AspectPhase
-import firrtl.annotations.{Annotation, ModuleTarget, NoTargetAnnotation, SingleTargetAnnotation}
-
-/** Contains all information needed to inject statements into a module
- *
- * Generated when a [[InjectingAspect]] is consumed by a [[AspectPhase]]
- * Consumed by [[InjectingTransform]]
- *
- * @param module Module to inject code into at the end of the module
- * @param s Statements to inject
- * @param modules Additional modules that may be instantiated by s
- * @param annotations Additional annotations that should be passed down compiler
- */
-case class InjectStatement(
- module: ModuleTarget,
- s: firrtl.ir.Statement,
- modules: Seq[firrtl.ir.DefModule],
- annotations: Seq[Annotation])
- extends SingleTargetAnnotation[ModuleTarget] {
- val target: ModuleTarget = module
- override def duplicate(n: ModuleTarget): Annotation = this.copy(module = n)
-}
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
deleted file mode 100644
index ecce19e1..00000000
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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
- }
-}
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala b/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
deleted file mode 100644
index 8a0b6ecb..00000000
--- a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.injecting
-
-import firrtl.{ir, ChirrtlForm, CircuitForm, CircuitState, Transform}
-
-import scala.collection.mutable
-
-/** Appends statements contained in [[InjectStatement]] annotations to the end of their corresponding modules
- *
- * Implemented with Chisel Aspects and the [[chisel3.aop.injecting]] library
- */
-class InjectingTransform extends Transform {
- override def inputForm: CircuitForm = ChirrtlForm
- override def outputForm: CircuitForm = ChirrtlForm
-
- override def execute(state: CircuitState): CircuitState = {
-
- val addStmtMap = mutable.HashMap[String, Seq[ir.Statement]]()
- val addModules = mutable.ArrayBuffer[ir.DefModule]()
-
- // Populate addStmtMap and addModules, return annotations in InjectStatements, and omit InjectStatement annotation
- val newAnnotations = state.annotations.flatMap {
- case InjectStatement(mt, s, addedModules, annotations) =>
- addModules ++= addedModules
- addStmtMap(mt.module) = s +: addStmtMap.getOrElse(mt.module, Nil)
- annotations
- case other => Seq(other)
- }
-
- // Append all statements to end of corresponding modules
- val newModules = state.circuit.modules.map { m: ir.DefModule =>
- m match {
- case m: ir.Module if addStmtMap.contains(m.name) =>
- m.copy(body = ir.Block(m.body +: addStmtMap(m.name)))
- case m: _root_.firrtl.ir.ExtModule if addStmtMap.contains(m.name) =>
- ir.Module(m.info, m.name, m.ports, ir.Block(addStmtMap(m.name)))
- case other: ir.DefModule => other
- }
- }
-
- // Return updated circuit and annotations
- val newCircuit = state.circuit.copy(modules = newModules ++ addModules)
- state.copy(annotations = newAnnotations, circuit = newCircuit)
- }
-}
diff --git a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala b/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
deleted file mode 100644
index 1340f253..00000000
--- a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.inspecting
-
-import chisel3.RawModule
-import chisel3.aop.Aspect
-import firrtl.AnnotationSeq
-
-/** Use for inspecting an elaborated design and printing out results
- *
- * @param inspect Given top-level design, print things and return nothing
- * @tparam T Type of top-level module
- */
-case class InspectingAspect[T <: RawModule](inspect: T => Unit) extends InspectorAspect[T](inspect)
-
-/** Extend to make custom inspections of an elaborated design and printing out results
- *
- * @param inspect Given top-level design, print things and return nothing
- * @tparam T Type of top-level module
- */
-abstract class InspectorAspect[T <: RawModule](inspect: T => Unit) extends Aspect[T] {
- override def toAnnotation(top: T): AnnotationSeq = {
- inspect(top)
- Nil
- }
-}