summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/experimental/hierarchy
diff options
context:
space:
mode:
authorJack Koenig2022-01-10 10:39:52 -0800
committerJack Koenig2022-01-10 15:53:55 -0800
commit3131c0daad41dea78bede4517669e376c41a325a (patch)
tree55baed78a6a01f80ff3952a08233ca553a19964f /core/src/main/scala/chisel3/experimental/hierarchy
parentdd36f97a82746cec0b25b94651581fe799e24579 (diff)
Apply scalafmt
Command: sbt scalafmtAll
Diffstat (limited to 'core/src/main/scala/chisel3/experimental/hierarchy')
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala33
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala20
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala33
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala1
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala4
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala9
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala251
7 files changed, 216 insertions, 135 deletions
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
index c7b51072..b498daf0 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
@@ -13,14 +13,17 @@ import chisel3.internal.BaseModule.IsClone
import firrtl.annotations.{IsModule, ModuleTarget}
/** User-facing Definition type.
- * Represents a definition of an object of type [[A]] which are marked as @instantiable
+ * Represents a definition of an object of type [[A]] which are marked as @instantiable
* Can be created using Definition.apply method.
- *
+ *
* These definitions are then used to create multiple [[Instance]]s.
*
* @param underlying The internal representation of the definition, which may be either be directly the object, or a clone of an object
*/
-final case class Definition[+A] private[chisel3] (private[chisel3] underlying: Underlying[A]) extends IsLookupable with SealedHierarchy[A] {
+final case class Definition[+A] private[chisel3] (private[chisel3] underlying: Underlying[A])
+ extends IsLookupable
+ with SealedHierarchy[A] {
+
/** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!!
* Instead, mark the field you are accessing with [[@public]]
*
@@ -35,14 +38,22 @@ final case class Definition[+A] private[chisel3] (private[chisel3] underlying: U
* @param lookup typeclass which contains the correct lookup function, based on the types of A and B
* @param macroGenerated a value created in the macro, to make it harder for users to use this API
*/
- def _lookup[B, C](that: A => B)(implicit lookup: Lookupable[B], macroGenerated: chisel3.internal.MacroGenerated): lookup.C = {
+ def _lookup[B, C](
+ that: A => B
+ )(
+ implicit lookup: Lookupable[B],
+ macroGenerated: chisel3.internal.MacroGenerated
+ ): lookup.C = {
lookup.definitionLookup(that, this)
}
/** @return the context of any Data's return from inside the instance */
private[chisel3] def getInnerDataContext: Option[BaseModule] = proto match {
case value: BaseModule =>
- val newChild = Module.do_pseudo_apply(new internal.BaseModule.DefinitionClone(value))(chisel3.internal.sourceinfo.UnlocatableSourceInfo, chisel3.ExplicitCompileOptions.Strict)
+ val newChild = Module.do_pseudo_apply(new internal.BaseModule.DefinitionClone(value))(
+ chisel3.internal.sourceinfo.UnlocatableSourceInfo,
+ chisel3.ExplicitCompileOptions.Strict
+ )
newChild._circuit = value._circuit.orElse(Some(value))
newChild._parent = None
Some(newChild)
@@ -50,14 +61,14 @@ final case class Definition[+A] private[chisel3] (private[chisel3] underlying: U
}
override def toDefinition: Definition[A] = this
- override def toInstance: Instance[A] = new Instance(underlying)
-
+ override def toInstance: Instance[A] = new Instance(underlying)
}
/** Factory methods for constructing [[Definition]]s */
object Definition extends SourceInfoDoc {
implicit class DefinitionBaseModuleExtensions[T <: BaseModule](d: Definition[T]) {
+
/** If this is an instance of a Module, returns the toTarget of this instance
* @return target of this instance
*/
@@ -68,6 +79,7 @@ object Definition extends SourceInfoDoc {
*/
def toAbsoluteTarget: IsModule = d.proto.toAbsoluteTarget
}
+
/** A construction method to build a Definition of a Module
*
* @param proto the Module being defined
@@ -82,7 +94,12 @@ object Definition extends SourceInfoDoc {
*
* @return the input module as a Definition
*/
- def do_apply[T <: BaseModule with IsInstantiable](proto: => T) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Definition[T] = {
+ def do_apply[T <: BaseModule with IsInstantiable](
+ proto: => T
+ )(
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ): Definition[T] = {
val dynamicContext = new DynamicContext(Nil)
Builder.globalNamespace.copyTo(dynamicContext.globalNamespace)
dynamicContext.inDefinition = true
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
index 4b8d3ccc..2016bb54 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
@@ -34,28 +34,27 @@ sealed trait Hierarchy[+A] {
* E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String]
* @return Whether underlying proto is of provided type (with caveats outlined above)
*/
- def isA[B : TypeTag]: Boolean = {
+ def isA[B: TypeTag]: Boolean = {
val tptag = implicitly[TypeTag[B]]
// drop any type information for the comparison, because the proto will not have that information.
- val name = tptag.tpe.toString.takeWhile(_ != '[')
+ val name = tptag.tpe.toString.takeWhile(_ != '[')
inBaseClasses(name)
}
-
// This code handles a special-case where, within an mdoc context, the type returned from
// scala reflection (typetag) looks different than when returned from java reflection.
// This function detects this case and reshapes the string to match.
private def modifyReplString(clz: String): String = {
- if(clz != null) {
+ if (clz != null) {
clz.split('.').toList match {
case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".")
- case other => clz
+ case other => clz
}
} else clz
}
private lazy val superClasses = calculateSuperClasses(proto.getClass())
private def calculateSuperClasses(clz: Class[_]): Set[String] = {
- if(clz != null) {
+ if (clz != null) {
Set(modifyReplString(clz.getCanonicalName())) ++
clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++
calculateSuperClasses(clz.getSuperclass())
@@ -65,7 +64,6 @@ sealed trait Hierarchy[+A] {
}
private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz)
-
/** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!!
* Instead, mark the field you are accessing with [[@public]]
*
@@ -80,7 +78,12 @@ sealed trait Hierarchy[+A] {
* @param lookup typeclass which contains the correct lookup function, based on the types of A and B
* @param macroGenerated a value created in the macro, to make it harder for users to use this API
*/
- def _lookup[B, C](that: A => B)(implicit lookup: Lookupable[B], macroGenerated: chisel3.internal.MacroGenerated): lookup.C
+ def _lookup[B, C](
+ that: A => B
+ )(
+ implicit lookup: Lookupable[B],
+ macroGenerated: chisel3.internal.MacroGenerated
+ ): lookup.C
/** @return Return the underlying Definition[A] of this Hierarchy[A] */
def toDefinition: Definition[A]
@@ -94,6 +97,7 @@ private[chisel3] trait SealedHierarchy[+A] extends Hierarchy[A]
object Hierarchy {
implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) {
+
/** Returns the toTarget of this hierarchy
* @return target of this hierarchy
*/
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
index 97b62c23..cc926771 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
@@ -11,12 +11,12 @@ import chisel3.experimental.BaseModule
import firrtl.annotations.IsModule
/** User-facing Instance type.
- * Represents a unique instance of type [[A]] which are marked as @instantiable
+ * Represents a unique instance of type [[A]] which are marked as @instantiable
* Can be created using Instance.apply method.
*
* @param underlying The internal representation of the instance, which may be either be directly the object, or a clone of an object
*/
-final case class Instance[+A] private [chisel3] (private[chisel3] underlying: Underlying[A]) extends SealedHierarchy[A] {
+final case class Instance[+A] private[chisel3] (private[chisel3] underlying: Underlying[A]) extends SealedHierarchy[A] {
underlying match {
case Proto(p: IsClone[_]) => chisel3.internal.throwException("Cannot have a Proto with a clone!")
case other => //Ok
@@ -24,16 +24,16 @@ final case class Instance[+A] private [chisel3] (private[chisel3] underlying: Un
/** @return the context of any Data's return from inside the instance */
private[chisel3] def getInnerDataContext: Option[BaseModule] = underlying match {
- case Proto(value: BaseModule) => Some(value)
- case Proto(value: IsInstantiable) => None
- case Clone(i: BaseModule) => Some(i)
+ case Proto(value: BaseModule) => Some(value)
+ case Proto(value: IsInstantiable) => None
+ case Clone(i: BaseModule) => Some(i)
case Clone(i: InstantiableClone[_]) => i.getInnerContext
}
/** @return the context this instance. Note that for non-module clones, getInnerDataContext will be the same as getClonedParent */
private[chisel3] def getClonedParent: Option[BaseModule] = underlying match {
case Proto(value: BaseModule) => value._parent
- case Clone(i: BaseModule) => i._parent
+ case Clone(i: BaseModule) => i._parent
case Clone(i: InstantiableClone[_]) => i.getInnerContext
}
@@ -51,19 +51,25 @@ final case class Instance[+A] private [chisel3] (private[chisel3] underlying: Un
* @param lookup typeclass which contains the correct lookup function, based on the types of A and B
* @param macroGenerated a value created in the macro, to make it harder for users to use this API
*/
- def _lookup[B, C](that: A => B)(implicit lookup: Lookupable[B], macroGenerated: chisel3.internal.MacroGenerated): lookup.C = {
+ def _lookup[B, C](
+ that: A => B
+ )(
+ implicit lookup: Lookupable[B],
+ macroGenerated: chisel3.internal.MacroGenerated
+ ): lookup.C = {
lookup.instanceLookup(that, this)
}
/** Returns the definition of this Instance */
override def toDefinition: Definition[A] = new Definition(Proto(proto))
- override def toInstance: Instance[A] = this
+ override def toInstance: Instance[A] = this
}
/** Factory methods for constructing [[Instance]]s */
object Instance extends SourceInfoDoc {
implicit class InstanceBaseModuleExtensions[T <: BaseModule](i: Instance[T]) {
+
/** If this is an instance of a Module, returns the toTarget of this instance
* @return target of this instance
*/
@@ -81,19 +87,26 @@ object Instance extends SourceInfoDoc {
}
}
+
/** A constructs an [[Instance]] from a [[Definition]]
*
* @param definition the Module being created
* @return an instance of the module definition
*/
- def apply[T <: BaseModule with IsInstantiable](definition: Definition[T]): Instance[T] = macro InstanceTransform.apply[T]
+ def apply[T <: BaseModule with IsInstantiable](definition: Definition[T]): Instance[T] =
+ macro InstanceTransform.apply[T]
/** A constructs an [[Instance]] from a [[Definition]]
*
* @param definition the Module being created
* @return an instance of the module definition
*/
- def do_apply[T <: BaseModule with IsInstantiable](definition: Definition[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Instance[T] = {
+ def do_apply[T <: BaseModule with IsInstantiable](
+ definition: Definition[T]
+ )(
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ): Instance[T] = {
val ports = experimental.CloneModuleAsRecord(definition.proto)
val clone = ports._parent.get.asInstanceOf[ModuleClone[T]]
clone._madeFromDefinition = true
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala
index 4f3c2d42..27e06d92 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala
@@ -6,7 +6,6 @@ package chisel3.experimental.hierarchy
* Instead, use the [[@instantiable]] annotation on your trait or class.
*
* This trait indicates whether a class can be returned from an Instance.
- *
*/
trait IsInstantiable
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala
index 37d29a43..a82cbd7d 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala
@@ -4,9 +4,9 @@ package chisel3.experimental.hierarchy
/** A User-extendable trait to mark metadata-containers, e.g. parameter case classes, as valid to return unchanged
* from an instance.
- *
+ *
* This should only be true of the metadata returned is identical for ALL instances!
- *
+ *
* @example For instances of the same proto, metadata or other construction parameters
* may be useful to access outside of the instance construction. For parameters that are
* the same for all instances, we should mark it as IsLookupable
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala b/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala
index c16cc633..d4818f63 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala
@@ -16,9 +16,12 @@ object LibraryHooks {
* definition's Underlying
* @note Implicitly requires being inside a Hierarchy Library Extension
*/
- def buildInstance[A](definition: Definition[A],
- createUnderlying: Underlying[A] => Underlying[A]
- )(implicit inside: InsideHierarchyLibraryExtension): Instance[A] = {
+ def buildInstance[A](
+ definition: Definition[A],
+ createUnderlying: Underlying[A] => Underlying[A]
+ )(
+ implicit inside: InsideHierarchyLibraryExtension
+ ): Instance[A] = {
new Instance(createUnderlying(definition.underlying))
}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
index ff4d676c..1223d6ce 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
@@ -11,18 +11,20 @@ import scala.collection.mutable.HashMap
import chisel3._
import chisel3.experimental.dataview.{isView, reify, reifySingleData}
import chisel3.internal.firrtl.{Arg, ILit, Index, Slot, ULit}
-import chisel3.internal.{AggregateViewBinding, Builder, ChildBinding, ViewBinding, ViewParent, throwException}
+import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBinding, ViewBinding, ViewParent}
/** Represents lookup typeclass to determine how a value accessed from an original IsInstantiable
* should be tweaked to return the Instance's version
* Sealed.
*/
-@implicitNotFound("@public is only legal within a class marked @instantiable and only on vals of type" +
- " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable or Option")
+@implicitNotFound(
+ "@public is only legal within a class marked @instantiable and only on vals of type" +
+ " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable or Option"
+)
trait Lookupable[-B] {
type C // Return type of the lookup
/** Function called to modify the returned value of type B from A, into C
- *
+ *
* @param that function that selects B from A
* @param instance Instance of A, used to determine C's context
* @return
@@ -35,8 +37,8 @@ trait Lookupable[-B] {
* @param definition Definition of A, used to determine C's context
* @return
*/
- def definitionLookup[A](that: A => B, definition: Definition[A]): C
- protected def getProto[A](h: Hierarchy[A]): A = h.proto
+ def definitionLookup[A](that: A => B, definition: Definition[A]): C
+ protected def getProto[A](h: Hierarchy[A]): A = h.proto
protected def getUnderlying[A](h: Hierarchy[A]): Underlying[A] = h.underlying
}
@@ -48,8 +50,13 @@ object Lookupable {
* @param context new context
* @return
*/
- private[chisel3] def cloneDataToContext[T <: Data](data: T, context: BaseModule)
- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
+ private[chisel3] def cloneDataToContext[T <: Data](
+ data: T,
+ context: BaseModule
+ )(
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ): T = {
internal.requireIsHardware(data, "cross module reference type")
data._parent match {
case None => data
@@ -68,11 +75,18 @@ object Lookupable {
}
// The business logic of lookupData
// Also called by cloneViewToContext which potentially needs to lookup stuff from ioMap or the cache
- private[chisel3] def doLookupData[A, B <: Data](data: B, cache: HashMap[Data, Data], ioMap: Option[Map[Data, Data]], context: Option[BaseModule])
- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): B = {
+ private[chisel3] def doLookupData[A, B <: Data](
+ data: B,
+ cache: HashMap[Data, Data],
+ ioMap: Option[Map[Data, Data]],
+ context: Option[BaseModule]
+ )(
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ): B = {
def impl[C <: Data](d: C): C = d match {
case x: Data if ioMap.nonEmpty && ioMap.get.contains(x) => ioMap.get(x).asInstanceOf[C]
- case x: Data if cache.contains(x) => cache(x).asInstanceOf[C]
+ case x: Data if cache.contains(x) => cache(x).asInstanceOf[C]
case _ =>
assert(context.nonEmpty) // TODO is this even possible? Better error message here
val ret = cloneDataToContext(d, context.get)
@@ -105,12 +119,13 @@ object Lookupable {
* Invariants that elt is a Child of something of the type of data is dynamically checked as we traverse
*/
private def mapRootAndExtractSubField[A <: Data](arg: A, f: Data => Data): A = {
- def err(msg: String) = throwException(s"Internal Error! $msg")
+ def err(msg: String) = throwException(s"Internal Error! $msg")
def unrollCoordinates(res: List[Arg], d: Data): (List[Arg], Data) = d.binding.get match {
- case ChildBinding(parent) => d.getRef match {
- case arg @ (_: Slot | _: Index) => unrollCoordinates(arg :: res, parent)
- case other => err(s"Unroll coordinates failed for '$arg'! Unexpected arg '$other'")
- }
+ case ChildBinding(parent) =>
+ d.getRef match {
+ case arg @ (_: Slot | _: Index) => unrollCoordinates(arg :: res, parent)
+ case other => err(s"Unroll coordinates failed for '$arg'! Unexpected arg '$other'")
+ }
case _ => (res, d)
}
def applyCoordinates(fullCoor: List[Arg], start: Data): Data = {
@@ -133,15 +148,22 @@ object Lookupable {
try {
result.asInstanceOf[A]
} catch {
- case _: ClassCastException => err(s"Applying '$coor' to '$newRoot' somehow resulted in '$result'")
+ case _: ClassCastException => err(s"Applying '$coor' to '$newRoot' somehow resulted in '$result'")
}
}
// TODO this logic is complicated, can any of it be unified with viewAs?
// If `.viewAs` would capture its arguments, we could potentially use it
// TODO Describe what this is doing at a high level
- private[chisel3] def cloneViewToContext[A, B <: Data](data: B, cache: HashMap[Data, Data], ioMap: Option[Map[Data, Data]], context: Option[BaseModule])
- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): B = {
+ private[chisel3] def cloneViewToContext[A, B <: Data](
+ data: B,
+ cache: HashMap[Data, Data],
+ ioMap: Option[Map[Data, Data]],
+ context: Option[BaseModule]
+ )(
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ): B = {
// alias to shorten lookups
def lookupData[C <: Data](d: C) = doLookupData(d, cache, ioMap, context)
@@ -150,29 +172,31 @@ object Lookupable {
// We have to lookup the target(s) of the view since they may need to be underlying into the current context
val newBinding = data.topBinding match {
case ViewBinding(target) => ViewBinding(lookupData(reify(target)))
- case avb @ AggregateViewBinding(map, targetOpt) => data match {
- case _: Element => ViewBinding(lookupData(reify(map(data))))
- case _: Aggregate =>
- // Provide a 1:1 mapping if possible
- val singleTargetOpt = targetOpt.filter(_ => avb == data.binding.get).flatMap(reifySingleData)
- singleTargetOpt match {
- case Some(singleTarget) => // It is 1:1!
- // This is a little tricky because the values in newMap need to point to Elements of newTarget
- val newTarget = lookupData(singleTarget)
- val newMap = coiterate(result, data).map { case (res, from) =>
- (res: Data) -> mapRootAndExtractSubField(map(from), _ => newTarget)
- }.toMap
- AggregateViewBinding(newMap, Some(newTarget))
+ case avb @ AggregateViewBinding(map, targetOpt) =>
+ data match {
+ case _: Element => ViewBinding(lookupData(reify(map(data))))
+ case _: Aggregate =>
+ // Provide a 1:1 mapping if possible
+ val singleTargetOpt = targetOpt.filter(_ => avb == data.binding.get).flatMap(reifySingleData)
+ singleTargetOpt match {
+ case Some(singleTarget) => // It is 1:1!
+ // This is a little tricky because the values in newMap need to point to Elements of newTarget
+ val newTarget = lookupData(singleTarget)
+ val newMap = coiterate(result, data).map {
+ case (res, from) =>
+ (res: Data) -> mapRootAndExtractSubField(map(from), _ => newTarget)
+ }.toMap
+ AggregateViewBinding(newMap, Some(newTarget))
- case None => // No 1:1 mapping so we have to do a flat binding
- // Just remap each Element of this aggregate
- val newMap = coiterate(result, data).map {
- // Upcast res to Data since Maps are invariant in the Key type parameter
- case (res, from) => (res: Data) -> lookupData(reify(map(from)))
- }.toMap
- AggregateViewBinding(newMap, None)
- }
- }
+ case None => // No 1:1 mapping so we have to do a flat binding
+ // Just remap each Element of this aggregate
+ val newMap = coiterate(result, data).map {
+ // Upcast res to Data since Maps are invariant in the Key type parameter
+ case (res, from) => (res: Data) -> lookupData(reify(map(from)))
+ }.toMap
+ AggregateViewBinding(newMap, None)
+ }
+ }
}
// TODO Unify the following with `.viewAs`
@@ -188,7 +212,7 @@ object Lookupable {
case (agg: Aggregate, _) if agg != result =>
Builder.unnamedViews += agg
case _ => // Do nothing
- }
+ }
}
result.bind(newBinding)
@@ -196,6 +220,7 @@ object Lookupable {
result.forceName(None, "view", Builder.viewNamespace)
result
}
+
/** Given a module (either original or a clone), clone it to a new context
*
* This function effectively recurses up the parents of module to find whether:
@@ -208,8 +233,13 @@ object Lookupable {
* @param context new context
* @return original or clone in the new context
*/
- private[chisel3] def cloneModuleToContext[T <: BaseModule](module: Underlying[T], context: BaseModule)
- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Underlying[T] = {
+ private[chisel3] def cloneModuleToContext[T <: BaseModule](
+ module: Underlying[T],
+ context: BaseModule
+ )(
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ): Underlying[T] = {
// Recursive call
def rec[A <: BaseModule](m: A): Underlying[A] = {
def clone(x: A, p: Option[BaseModule], name: () => String): Underlying[A] = {
@@ -221,7 +251,7 @@ object Lookupable {
case (c, ctx) if ctx == c => Proto(c)
case (c, ctx: IsClone[_]) if ctx.hasSameProto(c) => Clone(ctx.asInstanceOf[IsClone[A]])
case (c, ctx) if c._parent.isEmpty => Proto(c)
- case (_, _) =>
+ case (_, _) =>
cloneModuleToContext(Proto(m._parent.get), context) match {
case Proto(p) => Proto(m)
case Clone(p: BaseModule) =>
@@ -254,93 +284,107 @@ object Lookupable {
type B = X
type C = X
def definitionLookup[A](that: A => B, definition: Definition[A]): C = that(definition.proto)
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = that(instance.proto)
+ def instanceLookup[A](that: A => B, instance: Instance[A]): C = that(instance.proto)
}
- implicit def lookupInstance[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[Instance[B]] {
- type C = Instance[B]
- def definitionLookup[A](that: A => Instance[B], definition: Definition[A]): C = {
- val ret = that(definition.proto)
- new Instance(cloneModuleToContext(ret.underlying, definition.getInnerDataContext.get))
- }
- def instanceLookup[A](that: A => Instance[B], instance: Instance[A]): C = {
- val ret = that(instance.proto)
- instance.underlying match {
- // If instance is just a normal module, no changing of context is necessary
- case Proto(_) => new Instance(ret.underlying)
- case Clone(_) => new Instance(cloneModuleToContext(ret.underlying, instance.getInnerDataContext.get))
+ implicit def lookupInstance[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
+ new Lookupable[Instance[B]] {
+ type C = Instance[B]
+ def definitionLookup[A](that: A => Instance[B], definition: Definition[A]): C = {
+ val ret = that(definition.proto)
+ new Instance(cloneModuleToContext(ret.underlying, definition.getInnerDataContext.get))
}
- }
- }
-
- implicit def lookupModule[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[B] {
- type C = Instance[B]
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
- val ret = that(definition.proto)
- new Instance(cloneModuleToContext(Proto(ret), definition.getInnerDataContext.get))
- }
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
- val ret = that(instance.proto)
- instance.underlying match {
- // If instance is just a normal module, no changing of context is necessary
- case Proto(_) => new Instance(Proto(ret))
- case Clone(_) => new Instance(cloneModuleToContext(Proto(ret), instance.getInnerDataContext.get))
+ def instanceLookup[A](that: A => Instance[B], instance: Instance[A]): C = {
+ val ret = that(instance.proto)
+ instance.underlying match {
+ // If instance is just a normal module, no changing of context is necessary
+ case Proto(_) => new Instance(ret.underlying)
+ case Clone(_) => new Instance(cloneModuleToContext(ret.underlying, instance.getInnerDataContext.get))
+ }
}
}
- }
- implicit def lookupData[B <: Data](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[B] {
- type C = B
- def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
- val ret = that(definition.proto)
- if (isView(ret)) {
- ??? // TODO!!!!!! cloneViewToContext(ret, instance, ioMap, instance.getInnerDataContext)
- } else {
- doLookupData(ret, definition.cache, None, definition.getInnerDataContext)
+ implicit def lookupModule[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
+ new Lookupable[B] {
+ type C = Instance[B]
+ def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
+ val ret = that(definition.proto)
+ new Instance(cloneModuleToContext(Proto(ret), definition.getInnerDataContext.get))
}
- }
- def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
- val ret = that(instance.proto)
- val ioMap: Option[Map[Data, Data]] = instance.underlying match {
- case Clone(x: ModuleClone[_]) => Some(x.ioMap)
- case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap)
- case _ => None
+ def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
+ val ret = that(instance.proto)
+ instance.underlying match {
+ // If instance is just a normal module, no changing of context is necessary
+ case Proto(_) => new Instance(Proto(ret))
+ case Clone(_) => new Instance(cloneModuleToContext(Proto(ret), instance.getInnerDataContext.get))
+ }
}
- if (isView(ret)) {
- cloneViewToContext(ret, instance.cache, ioMap, instance.getInnerDataContext)
- } else {
- doLookupData(ret, instance.cache, ioMap, instance.getInnerDataContext)
+ }
+
+ implicit def lookupData[B <: Data](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
+ new Lookupable[B] {
+ type C = B
+ def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
+ val ret = that(definition.proto)
+ if (isView(ret)) {
+ ??? // TODO!!!!!! cloneViewToContext(ret, instance, ioMap, instance.getInnerDataContext)
+ } else {
+ doLookupData(ret, definition.cache, None, definition.getInnerDataContext)
+ }
}
+ def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
+ val ret = that(instance.proto)
+ val ioMap: Option[Map[Data, Data]] = instance.underlying match {
+ case Clone(x: ModuleClone[_]) => Some(x.ioMap)
+ case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap)
+ case _ => None
+ }
+ if (isView(ret)) {
+ cloneViewToContext(ret, instance.cache, ioMap, instance.getInnerDataContext)
+ } else {
+ doLookupData(ret, instance.cache, ioMap, instance.getInnerDataContext)
+ }
+ }
}
- }
import scala.language.higherKinds // Required to avoid warning for lookupIterable type parameter
- implicit def lookupIterable[B, F[_] <: Iterable[_]](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions, lookupable: Lookupable[B]) = new Lookupable[F[B]] {
+ implicit def lookupIterable[B, F[_] <: Iterable[_]](
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions,
+ lookupable: Lookupable[B]
+ ) = new Lookupable[F[B]] {
type C = F[lookupable.C]
def definitionLookup[A](that: A => F[B], definition: Definition[A]): C = {
val ret = that(definition.proto).asInstanceOf[Iterable[B]]
- ret.map{ x: B => lookupable.definitionLookup[A](_ => x, definition) }.asInstanceOf[C]
+ ret.map { x: B => lookupable.definitionLookup[A](_ => x, definition) }.asInstanceOf[C]
}
def instanceLookup[A](that: A => F[B], instance: Instance[A]): C = {
import instance._
val ret = that(proto).asInstanceOf[Iterable[B]]
- ret.map{ x: B => lookupable.instanceLookup[A](_ => x, instance) }.asInstanceOf[C]
+ ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) }.asInstanceOf[C]
}
}
- implicit def lookupOption[B](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions, lookupable: Lookupable[B]) = new Lookupable[Option[B]] {
+ implicit def lookupOption[B](
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions,
+ lookupable: Lookupable[B]
+ ) = new Lookupable[Option[B]] {
type C = Option[lookupable.C]
def definitionLookup[A](that: A => Option[B], definition: Definition[A]): C = {
val ret = that(definition.proto)
- ret.map{ x: B => lookupable.definitionLookup[A](_ => x, definition) }
+ ret.map { x: B => lookupable.definitionLookup[A](_ => x, definition) }
}
def instanceLookup[A](that: A => Option[B], instance: Instance[A]): C = {
import instance._
val ret = that(proto)
- ret.map{ x: B => lookupable.instanceLookup[A](_ => x, instance) }
+ ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) }
}
}
- implicit def lookupIsInstantiable[B <: IsInstantiable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[B] {
+ implicit def lookupIsInstantiable[B <: IsInstantiable](
+ implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions
+ ) = new Lookupable[B] {
type C = Instance[B]
def definitionLookup[A](that: A => B, definition: Definition[A]): C = {
val ret = that(definition.proto)
@@ -360,8 +404,9 @@ object Lookupable {
}
}
- implicit def lookupIsLookupable[B <: IsLookupable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new SimpleLookupable[B]()
-
+ implicit def lookupIsLookupable[B <: IsLookupable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) =
+ new SimpleLookupable[B]()
+
implicit val lookupInt = new SimpleLookupable[Int]()
implicit val lookupByte = new SimpleLookupable[Byte]()
implicit val lookupShort = new SimpleLookupable[Short]()