summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3
diff options
context:
space:
mode:
authorAdam Izraelevitz2021-10-27 16:52:56 -0700
committerGitHub2021-10-27 23:52:56 +0000
commitef8a9c2148f01e058d2986c9d64f0c35f640790c (patch)
treead2c31ee8216758882cc7364c93a51c14050a6a4 /core/src/main/scala/chisel3
parent2a68cc0636580db1a5fa98e87727bb3ec870e0bc (diff)
Add Select APIs for Hierarchy package (#2210)
* Add Hierarchy trait * Add Hierarchy trait * Add Hierarchy scaladoc * Add license * Add isA and tests * Add back isA * Add new Select APIs for hierarchy package * Update scaladoc * Write outlines for tests * Add tests and fixes to new Select functions * Make calculate via lazy val * Apply suggestions from code review Co-authored-by: Megan Wachs <megan@sifive.com> * Apply suggestions from code review Co-authored-by: Megan Wachs <megan@sifive.com> * Clean up scaladoc * Add shouldNot compile * Apply suggestions from code review Co-authored-by: Megan Wachs <megan@sifive.com> * Bugfix all funcs should analyze root too * Add mdoc, bugfix toDefinition * Make func private, add scaladoc * Update src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala Co-authored-by: Jack Koenig <koenig@sifive.com> * Made protected vals private * Apply suggestions from code review Co-authored-by: Jack Koenig <koenig@sifive.com> * Address code review comments * Added additional null check Co-authored-by: Megan Wachs <megan@sifive.com> Co-authored-by: Jack Koenig <koenig@sifive.com>
Diffstat (limited to 'core/src/main/scala/chisel3')
-rw-r--r--core/src/main/scala/chisel3/Module.scala26
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala5
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala20
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala7
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala6
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala2
6 files changed, 55 insertions, 11 deletions
diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala
index 1ae65969..263aee61 100644
--- a/core/src/main/scala/chisel3/Module.scala
+++ b/core/src/main/scala/chisel3/Module.scala
@@ -88,6 +88,16 @@ object Module extends SourceInfoDoc {
def reset: Reset = Builder.forcedReset
/** Returns the current Module */
def currentModule: Option[BaseModule] = Builder.currentModule
+
+ private[chisel3] def do_pseudo_apply[T <: BaseModule](bc: => T)
+ (implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions): T = {
+ val parent = Builder.currentModule
+
+ val module: T = bc // bc is actually evaluated here
+
+ module
+ }
}
/** Abstract base class for Modules, which behave much like Verilog modules.
@@ -357,13 +367,19 @@ package experimental {
//
// Builder Internals - this tracks which Module RTL construction belongs to.
//
- if (!Builder.readyForModuleConstr) {
- throwException("Error: attempted to instantiate a Module without wrapping it in Module().")
+ this match {
+ case _: PseudoModule =>
+ case other =>
+ if (!Builder.readyForModuleConstr) {
+ throwException("Error: attempted to instantiate a Module without wrapping it in Module().")
+ }
}
- readyForModuleConstr = false
+ if (Builder.hasDynamicContext) {
+ readyForModuleConstr = false
- Builder.currentModule = Some(this)
- Builder.whenStack = Nil
+ Builder.currentModule = Some(this)
+ Builder.whenStack = Nil
+ }
//
// Module Construction Internals
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
index 3c4c3c84..8f0c88ad 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
@@ -42,13 +42,16 @@ final case class Definition[+A] private[chisel3] (private[chisel3] cloned: Eithe
/** @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_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)
case value: IsInstantiable => None
}
+ override def toDefinition: Definition[A] = this
+ override def toInstance: Instance[A] = new Instance(cloned)
+
}
/** Factory methods for constructing [[Definition]]s */
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
index d1ccfb1b..559b0e1a 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala
@@ -40,10 +40,22 @@ sealed trait Hierarchy[+A] {
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) {
+ clz.split('.').toList match {
+ case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".")
+ case other => clz
+ }
+ } else clz
+ }
private lazy val superClasses = calculateSuperClasses(proto.getClass())
private def calculateSuperClasses(clz: Class[_]): Set[String] = {
if(clz != null) {
- Set(clz.getCanonicalName()) ++
+ Set(modifyReplString(clz.getCanonicalName())) ++
clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++
calculateSuperClasses(clz.getSuperclass())
} else {
@@ -68,6 +80,12 @@ sealed trait Hierarchy[+A] {
* @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
+
+ /** @return Return the underlying Definition[A] of this Hierarchy[A] */
+ def toDefinition: Definition[A]
+
+ /** @return Convert this Hierarchy[A] as a top-level Instance[A] */
+ def toInstance: Instance[A]
}
// Used to effectively seal Hierarchy, without requiring Definition and Instance to be in this file.
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
index bda52c1b..49f882eb 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala
@@ -17,6 +17,10 @@ import firrtl.annotations.IsModule
* @param cloned 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] cloned: Either[A, IsClone[A]]) extends SealedHierarchy[A] {
+ cloned match {
+ case Left(p: IsClone[_]) => chisel3.internal.throwException("Cannot have a Left with a clone!")
+ case other => //Ok
+ }
/** @return the context of any Data's return from inside the instance */
private[chisel3] def getInnerDataContext: Option[BaseModule] = cloned match {
@@ -52,7 +56,8 @@ final case class Instance[+A] private [chisel3] (private[chisel3] cloned: Either
}
/** Returns the definition of this Instance */
- def toDefinition: Definition[A] = new Definition(Left(proto))
+ override def toDefinition: Definition[A] = new Definition(Left(proto))
+ override def toInstance: Instance[A] = this
}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
index 2242c1c4..771e2070 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
@@ -211,7 +211,7 @@ private[chisel3] object Lookupable {
// Recursive call
def rec[A <: BaseModule](m: A): Either[A, IsClone[A]] = {
def clone(x: A, p: Option[BaseModule], name: () => String): Either[A, IsClone[A]] = {
- val newChild = Module.do_apply(new internal.BaseModule.InstanceClone(x, name))
+ val newChild = Module.do_pseudo_apply(new internal.BaseModule.InstanceClone(x, name))
newChild._parent = p
Right(newChild)
}
@@ -233,7 +233,7 @@ private[chisel3] object Lookupable {
rec(m) match {
case Left(mx) => Right(mx)
case Right(i: InstanceClone[_]) =>
- val newChild = Module.do_apply(new InstanceClone(m._proto, () => m.instanceName))
+ val newChild = Module.do_pseudo_apply(new InstanceClone(m._proto, () => m.instanceName))
newChild._parent = i._parent
Right(newChild)
}
@@ -241,7 +241,7 @@ private[chisel3] object Lookupable {
rec(m) match {
case Left(mx) => Right(mx)
case Right(i: InstanceClone[_]) =>
- val newChild = Module.do_apply(new InstanceClone(m._proto, () => m.instanceName))
+ val newChild = Module.do_pseudo_apply(new InstanceClone(m._proto, () => m.instanceName))
newChild._parent = i._parent
Right(newChild)
}
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index 57e7578a..3761b371 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -561,6 +561,8 @@ private[chisel3] object Builder extends LazyLogging {
// A bare api call is, e.g. calling Wire() from the scala console).
)
}
+ def hasDynamicContext: Boolean = dynamicContextVar.value.isDefined
+
def readyForModuleConstr: Boolean = dynamicContext.readyForModuleConstr
def readyForModuleConstr_=(target: Boolean): Unit = {
dynamicContext.readyForModuleConstr = target