diff options
| author | Jack Koenig | 2022-01-10 10:39:52 -0800 |
|---|---|---|
| committer | Jack Koenig | 2022-01-10 15:53:55 -0800 |
| commit | 3131c0daad41dea78bede4517669e376c41a325a (patch) | |
| tree | 55baed78a6a01f80ff3952a08233ca553a19964f /core/src/main/scala/chisel3/experimental/hierarchy | |
| parent | dd36f97a82746cec0b25b94651581fe799e24579 (diff) | |
Apply scalafmt
Command:
sbt scalafmtAll
Diffstat (limited to 'core/src/main/scala/chisel3/experimental/hierarchy')
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]() |
