summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
diff options
context:
space:
mode:
authorRichard Lin2017-06-26 18:35:46 -0700
committerGitHub2017-06-26 18:35:46 -0700
commitaaee58d374dc3f3a088856da13a6a59ecffb2cac (patch)
tree790828de9a9fbb1dfd26635eebaf27668a4cc8df /chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
parent91850ec917a432e9e3db588e7711c8a82801eb49 (diff)
Directions internals mega-refactor (#617)
Part 1 of mega-change in #578 Major notes: - Input(...) and Output(...) now (effectively) recursively override their elements' directions - Nodes given userDirection (Input, Output, Flip - what the user assigned to _that_ node) and actualDirection (Input, Output, None, but also Bidirectional and BidirectionalFlip for mostly Aggregates), because of the above (since a higher-level Input(...) can override the locally specified user direction). - DataMirror (node reflection APIs) added to chisel3.experimental. This provides ways to query the user given direction of a node as well as the actual direction. - checkSynthesizable replaced with requireIsHardware and requireIsChiselType and made available in chisel3.experimental. Internal changes notes: - toType moved into Emitter, this makes the implementation cleaner especially considering that Vec types can't be flipped in FIRRTL. This also more clearly separates Chisel frontend from FIRRTL emission. - Direction separated from Bindings, both are now fields in Data, and all nodes are given hierarchical directions (Aggregates may be Bidirectional). The actualDirection at the Element (leaf) level should be the same as binding directions previously. - Bindings are hierarchical, children (of a, for example, Bundle) have a ChildBinding that points to their parent. This is different than the previous scheme where Bindings only applied at the Element (leaf) level. - Lots of small misc clean up. Future PRs will address other parts of #578, including stricter direction checks that aren't a side-effect of this internal refactor, stricter checks and splitting of binding operations (Wire vs. WireInit), and node operations not introduced here (getType and deprecation of chiselCloneType). Since those shouldn't mess with internals, those should be much smaller.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala91
1 files changed, 34 insertions, 57 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
index 0e5d4e8b..f2b2b7e1 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
@@ -138,15 +138,14 @@ object BiConnect {
// This function checks if element-level connection operation allowed.
// Then it either issues it or throws the appropriate exception.
def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Element, right: Element, context_mod: UserModule): Unit = {
- import Direction.{Input, Output} // Using extensively so import these
+ import BindingDirection.{Internal, Input, Output} // Using extensively so import these
// If left or right have no location, assume in context module
// This can occur if one of them is a literal, unbound will error previously
- val left_mod: BaseModule = left.binding.location.getOrElse(context_mod)
- val right_mod: BaseModule = right.binding.location.getOrElse(context_mod)
+ val left_mod: BaseModule = left.topBinding.location.getOrElse(context_mod)
+ val right_mod: BaseModule = right.topBinding.location.getOrElse(context_mod)
- val left_direction: Option[Direction] = left.binding.direction
- val right_direction: Option[Direction] = right.binding.direction
- // None means internal
+ 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) &&
@@ -154,15 +153,15 @@ object BiConnect {
// Thus, right node better be a port node and thus have a direction hint
((left_direction, right_direction): @unchecked) match {
// CURRENT MOD CHILD MOD
- case (Some(Input), Some(Input)) => issueConnectL2R(left, right)
- case (None, Some(Input)) => issueConnectL2R(left, right)
+ case (Input, Input) => issueConnectL2R(left, right)
+ case (Internal, Input) => issueConnectL2R(left, right)
- case (Some(Output), Some(Output)) => issueConnectR2L(left, right)
- case (None, Some(Output)) => issueConnectR2L(left, right)
+ case (Output, Output) => issueConnectR2L(left, right)
+ case (Internal, Output) => issueConnectR2L(left, right)
- case (Some(Input), Some(Output)) => throw BothDriversException
- case (Some(Output), Some(Input)) => throw NeitherDriverException
- case (_, None) => throw UnknownRelationException
+ case (Input, Output) => throw BothDriversException
+ case (Output, Input) => throw NeitherDriverException
+ case (_, Internal) => throw UnknownRelationException
}
}
@@ -172,15 +171,15 @@ object BiConnect {
// Thus, left node better be a port node and thus have a direction hint
((left_direction, right_direction): @unchecked) match {
// CHILD MOD CURRENT MOD
- case (Some(Input), Some(Input)) => issueConnectR2L(left, right)
- case (Some(Input), None) => issueConnectR2L(left, right)
+ case (Input, Input) => issueConnectR2L(left, right)
+ case (Input, Internal) => issueConnectR2L(left, right)
- case (Some(Output), Some(Output)) => issueConnectL2R(left, right)
- case (Some(Output), None) => issueConnectL2R(left, right)
+ case (Output, Output) => issueConnectL2R(left, right)
+ case (Output, Internal) => issueConnectL2R(left, right)
- case (Some(Input), Some(Output)) => throw NeitherDriverException
- case (Some(Output), Some(Input)) => throw BothDriversException
- case (None, _) => throw UnknownRelationException
+ case (Input, Output) => throw NeitherDriverException
+ case (Output, Input) => throw BothDriversException
+ case (Internal, _) => throw UnknownRelationException
}
}
@@ -188,39 +187,17 @@ object BiConnect {
else if( (context_mod == left_mod) && (context_mod == right_mod) ) {
((left_direction, right_direction): @unchecked) match {
// CURRENT MOD CURRENT MOD
- case (Some(Input), Some(Output)) => issueConnectL2R(left, right)
- case (Some(Input), None) => issueConnectL2R(left, right)
- case (None, Some(Output)) => issueConnectL2R(left, right)
+ case (Input, Output) => issueConnectL2R(left, right)
+ case (Input, Internal) => issueConnectL2R(left, right)
+ case (Internal, Output) => issueConnectL2R(left, right)
- case (Some(Output), Some(Input)) => issueConnectR2L(left, right)
- case (Some(Output), None) => issueConnectR2L(left, right)
- case (None, Some(Input)) => issueConnectR2L(left, right)
+ case (Output, Input) => issueConnectR2L(left, right)
+ case (Output, Internal) => issueConnectR2L(left, right)
+ case (Internal, Input) => issueConnectR2L(left, right)
- case (Some(Input), Some(Input)) => {
- if (connectCompileOptions.dontAssumeDirectionality) {
- throw BothDriversException
- } else {
- (left.binding, right.binding) match {
- case (PortBinding(_, _), PortBinding(_, _)) => throw BothDriversException
- case (PortBinding(_, _), _) => issueConnectL2R(left, right)
- case (_, PortBinding(_, _)) => issueConnectR2L(left, right)
- case _ => throw BothDriversException
- }
- }
- }
- case (Some(Output), Some(Output)) => {
- if (connectCompileOptions.dontAssumeDirectionality) {
- throw BothDriversException
- } else {
- (left.binding, right.binding) match {
- case (PortBinding(_, _), PortBinding(_, _)) => throw BothDriversException
- case (PortBinding(_, _), _) => issueConnectR2L(left, right)
- case (_, PortBinding(_, _)) => issueConnectL2R(left, right)
- case _ => throw BothDriversException
- }
- }
- }
- case (None, None) => {
+ case (Input, Input) => throw BothDriversException
+ case (Output, Output) => throw BothDriversException
+ case (Internal, Internal) => {
if (connectCompileOptions.dontAssumeDirectionality) {
throw UnknownDriverException
} else {
@@ -239,18 +216,18 @@ object BiConnect {
// Thus both nodes must be ports and have a direction hint
((left_direction, right_direction): @unchecked) match {
// CHILD MOD CHILD MOD
- case (Some(Input), Some(Output)) => issueConnectR2L(left, right)
- case (Some(Output), Some(Input)) => issueConnectL2R(left, right)
+ case (Input, Output) => issueConnectR2L(left, right)
+ case (Output, Input) => issueConnectL2R(left, right)
- case (Some(Input), Some(Input)) => throw NeitherDriverException
- case (Some(Output), Some(Output)) => throw BothDriversException
- case (_, None) =>
+ case (Input, Input) => throw NeitherDriverException
+ case (Output, Output) => throw BothDriversException
+ case (_, Internal) =>
if (connectCompileOptions.dontAssumeDirectionality) {
throw UnknownRelationException
} else {
issueConnectR2L(left, right)
}
- case (None, _) =>
+ case (Internal, _) =>
if (connectCompileOptions.dontAssumeDirectionality) {
throw UnknownRelationException
} else {