summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJustin Deters2020-08-11 18:28:12 -0500
committerGitHub2020-08-11 23:28:12 +0000
commite0c805171ddb9707b0f9fe93e5d85ef9cdcab044 (patch)
tree8b331390b99204b72c7abfab67351845b685f06c /core
parent3668532fabc4ba4eaf70cf0ad1a55522aa33cdb3 (diff)
Bug fix for manipulating submodules in aspects (#1538)
* Fixed the aspect as parent bug in Data and MonoConnect * refactored and cleaned up finding an aspect parent * Added aspect fix to the BiConnect class * added unit test for manipulating submodules via aspects * Refactored to move determination of proper parent to Builder and made logic simpler in MonoConnect, Data, and BiConnect * Removed unused function and provided Scaladoc for retrieveParent
Diffstat (limited to 'core')
-rw-r--r--core/src/main/scala/chisel3/Data.scala2
-rw-r--r--core/src/main/scala/chisel3/internal/BiConnect.scala13
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala22
-rw-r--r--core/src/main/scala/chisel3/internal/MonoConnect.scala13
4 files changed, 35 insertions, 15 deletions
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala
index b7859e91..bb7efedf 100644
--- a/core/src/main/scala/chisel3/Data.scala
+++ b/core/src/main/scala/chisel3/Data.scala
@@ -450,7 +450,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
val mod = topBindingOpt.flatMap(_.location)
topBindingOpt match {
case Some(tb: TopBinding) if (mod == Builder.currentModule) =>
- case Some(pb: PortBinding) if (mod.flatMap(_._parent) == Builder.currentModule) =>
+ case Some(pb: PortBinding) if (mod.flatMap(Builder.retrieveParent(_,Builder.currentModule.get)) == Builder.currentModule) =>
case _ =>
throwException(s"operand is not visible from the current module")
}
diff --git a/core/src/main/scala/chisel3/internal/BiConnect.scala b/core/src/main/scala/chisel3/internal/BiConnect.scala
index 8cc4bbaf..49cfeb75 100644
--- a/core/src/main/scala/chisel3/internal/BiConnect.scala
+++ b/core/src/main/scala/chisel3/internal/BiConnect.scala
@@ -222,12 +222,14 @@ private[chisel3] object BiConnect {
val left_mod: BaseModule = left.topBinding.location.getOrElse(context_mod)
val right_mod: BaseModule = right.topBinding.location.getOrElse(context_mod)
+ val left_parent = Builder.retrieveParent(left_mod, context_mod).getOrElse(None)
+ val right_parent = Builder.retrieveParent(right_mod, context_mod).getOrElse(None)
+
val left_direction = BindingDirection.from(left.topBinding, left.direction)
val right_direction = BindingDirection.from(right.topBinding, right.direction)
// CASE: Context is same module as left node and right node is in a child module
- if( (left_mod == context_mod) &&
- (right_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
+ if((left_mod == context_mod) && (right_parent == context_mod)) {
// Thus, right node better be a port node and thus have a direction hint
((left_direction, right_direction): @unchecked) match {
// CURRENT MOD CHILD MOD
@@ -244,8 +246,7 @@ private[chisel3] object BiConnect {
}
// CASE: Context is same module as right node and left node is in child module
- else if( (right_mod == context_mod) &&
- (left_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
+ else if((right_mod == context_mod) && (left_parent == context_mod)) {
// Thus, left node better be a port node and thus have a direction hint
((left_direction, right_direction): @unchecked) match {
// CHILD MOD CURRENT MOD
@@ -288,9 +289,7 @@ private[chisel3] object BiConnect {
// CASE: Context is the parent module of both the module containing left node
// and the module containing right node
// Note: This includes case when left and right in same module but in parent
- else if( (left_mod._parent.map(_ == context_mod).getOrElse(false)) &&
- (right_mod._parent.map(_ == context_mod).getOrElse(false))
- ) {
+ else if((left_parent == context_mod) && (right_parent == context_mod)) {
// Thus both nodes must be ports and have a direction hint
((left_direction, right_direction): @unchecked) match {
// CHILD MOD CHILD MOD
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index 3c6d7290..d05a69f7 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -427,6 +427,28 @@ private[chisel3] object Builder {
case Some(dynamicContext) => dynamicContext.aspectModule.get(module)
case _ => None
}
+ /** Retrieves the parent of a module based on the elaboration context
+ *
+ * @param module the module to get the parent of
+ * @param context the context the parent should be evaluated in
+ * @return the parent of the module provided
+ */
+ def retrieveParent(module: BaseModule, context: BaseModule): Option[BaseModule] = {
+ module._parent match {
+ case Some(parentModule) => { //if a parent exists investigate, otherwise return None
+ context match {
+ case aspect: ModuleAspect => { //if aspect context, do the translation
+ Builder.aspectModule(parentModule) match {
+ case Some(parentAspect) => Some(parentAspect) //we've found a translation
+ case _ => Some(parentModule) //no translation found
+ }
+ } //otherwise just return our parent
+ case _ => Some(parentModule)
+ }
+ }
+ case _ => None
+ }
+ }
def addAspect(module: BaseModule, aspect: BaseModule): Unit = {
dynamicContext.aspectModule += ((module, aspect))
}
diff --git a/core/src/main/scala/chisel3/internal/MonoConnect.scala b/core/src/main/scala/chisel3/internal/MonoConnect.scala
index dbc4f7f2..7edf6eba 100644
--- a/core/src/main/scala/chisel3/internal/MonoConnect.scala
+++ b/core/src/main/scala/chisel3/internal/MonoConnect.scala
@@ -193,6 +193,9 @@ private[chisel3] object MonoConnect {
val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException)
val source_mod: BaseModule = source.topBinding.location.getOrElse(context_mod)
+ val sink_parent = Builder.retrieveParent(sink_mod, context_mod).getOrElse(None)
+ val source_parent = Builder.retrieveParent(source_mod, context_mod).getOrElse(None)
+
val sink_direction = BindingDirection.from(sink.topBinding, sink.direction)
val source_direction = BindingDirection.from(source.topBinding, source.direction)
@@ -216,8 +219,7 @@ private[chisel3] object MonoConnect {
}
// CASE: Context is same module as sink node and right node is in a child module
- else if( (sink_mod == context_mod) &&
- (source_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
+ else if((sink_mod == context_mod) && (source_parent == context_mod)) {
// Thus, right node better be a port node and thus have a direction
((sink_direction, source_direction): @unchecked) match {
// SINK SOURCE
@@ -239,8 +241,7 @@ private[chisel3] object MonoConnect {
}
// CASE: Context is same module as source node and sink node is in child module
- else if( (source_mod == context_mod) &&
- (sink_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
+ else if((source_mod == context_mod) && (sink_parent == context_mod)) {
// Thus, left node better be a port node and thus have a direction
((sink_direction, source_direction): @unchecked) match {
// SINK SOURCE
@@ -254,9 +255,7 @@ private[chisel3] object MonoConnect {
// CASE: Context is the parent module of both the module containing sink node
// and the module containing source node
// Note: This includes case when sink and source in same module but in parent
- else if( (sink_mod._parent.map(_ == context_mod).getOrElse(false)) &&
- (source_mod._parent.map(_ == context_mod).getOrElse(false))
- ) {
+ else if((sink_parent == context_mod) && (source_parent == context_mod)) {
// Thus both nodes must be ports and have a direction
((sink_direction, source_direction): @unchecked) match {
// SINK SOURCE