summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
diff options
context:
space:
mode:
authorAdam Izraelevitz2017-10-26 12:39:42 -0700
committerJim Lawson2017-10-26 12:39:42 -0700
commitc313e137d4e562ef20195312501840ceab8cbc6a (patch)
tree37e290d3c5af672624b9ac267ccb33421acca84e /chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
parent8168a8eea6c3465966081c5acd0347e09791361c (diff)
Invalidateapi (#645)
* Require explicit connection to DontCare to generate "is invalid". * Add tests for RefNotInitializedException. Currently, we fail the when ... otherwise ... * Disable ScalaTest shrinking on error in ComplexAssignSpec. * fix broken merge; still some binding issues * cleanup DontCare connection checks; add missing directions to test module IOs * Have library code inherit compileOptions from the enclosing Module (if it exists). * work around current firrtl uninitialized references with Strict compile options and explicitInvalidate * more CompileOptions cleanup; move test-specific defines to package object * minimize differences with master * set default CompileOptions.explicitInvalidate to false until we fix the FIRRTL when issue * ignore the StrictCompiler property checks (until CompileOptions.explicitInvalidate is defaulted to true) * Revert "more CompileOptions cleanup; move test-specific defines to package object" This reverts commit e4486edcba990d150e76e08a2fc6abca033556e0. * Revert "work around current firrtl uninitialized references with Strict compile options and explicitInvalidate" This reverts commit 426faa430a62c3dac2dbdf33044d3386d4243157. * remove unused code * Convert to binding-based DontCare implementation * comment cleanup to minimize differences with master * Tentatively remove possibly redundant DefInvalid on module ports. * Respond to code review change request. - backout build.sbt change - correct indentation - handle bulk of DontCare semantics in elemConnect() - have DontCare extend Element, not Data (eliminate most Object specific methods - add comments indicating reason for explicit DontCare connections * Initialize test elements without requiring a DontCare. * Respond to review change requests. - DontCare should work on left or right side in BiDirectional connections - call bind() to set DontCare binding instead of messing with internal variables - DontCares are only equivalent with DontCares - clean up processWhens() definition * Eliminate DontCare connection to inputs in MonoConnect(). * Pull aggregates apart for the purpose of DontCare connections. * Restore the explicit (conditionally executed) ports DefInvalidin ImplicitModule() * Don't add DontCare's to the module list of _ids. * Add missing DefInvalid() to LegacyModule(). * Respond to review requests: add DontCare BiConnect Vec, remove null parent hack to avoid addId(), initialize singletons early in Builder * Move DontCare out of chisel3.experimental.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala87
1 files changed, 78 insertions, 9 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
index f2b2b7e1..d056efba 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
@@ -2,10 +2,8 @@
package chisel3.core
-import chisel3.internal.Builder
import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl.{Attach, Connect}
-import chisel3.internal.throwException
+import chisel3.internal.firrtl.{Connect, DefInvalid}
import scala.language.experimental.macros
import chisel3.internal.sourceinfo._
@@ -46,6 +44,8 @@ object BiConnect {
BiConnectException(s": Left ($left) and Right ($right) have different types.")
def AttachAlreadyBulkConnectedException(sourceInfo: SourceInfo) =
BiConnectException(sourceInfo.makeMessage(": Analog previously bulk connected at " + _))
+ def DontCareCantBeSink =
+ BiConnectException(": DontCare cannot be a connection sink (LHS)")
/** This function is what recursively tries to connect a left and right together
@@ -54,7 +54,7 @@ object BiConnect {
* during the recursive decent and then rethrow them with extra information added.
* This gives the user a 'path' to where in the connections things went wrong.
*/
- def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Data, right: Data, context_mod: UserModule): Unit =
+ def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Data, right: Data, context_mod: UserModule): Unit = {
(left, right) match {
// Handle element case (root case)
case (left_a: Analog, right_a: Analog) =>
@@ -69,9 +69,11 @@ object BiConnect {
// TODO(twigg): Verify the element-level classes are connectable
}
// Handle Vec case
- case (left_v: Vec[Data @unchecked], right_v: Vec[Data @unchecked]) => {
- if(left_v.length != right_v.length) { throw MismatchedVecException }
- for(idx <- 0 until left_v.length) {
+ case (left_v: Vec[Data@unchecked], right_v: Vec[Data@unchecked]) => {
+ if (left_v.length != right_v.length) {
+ throw MismatchedVecException
+ }
+ for (idx <- 0 until left_v.length) {
try {
implicit val compileOptions = connectCompileOptions
connect(sourceInfo, connectCompileOptions, left_v(idx), right_v(idx), context_mod)
@@ -80,6 +82,28 @@ object BiConnect {
}
}
}
+ // Handle Vec connected to DontCare
+ case (left_v: Vec[Data@unchecked], DontCare) => {
+ for (idx <- 0 until left_v.length) {
+ try {
+ implicit val compileOptions = connectCompileOptions
+ connect(sourceInfo, connectCompileOptions, left_v(idx), right, context_mod)
+ } catch {
+ case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
+ }
+ }
+ }
+ // Handle DontCare connected to Vec
+ case (DontCare, right_v: Vec[Data@unchecked]) => {
+ for (idx <- 0 until right_v.length) {
+ try {
+ implicit val compileOptions = connectCompileOptions
+ connect(sourceInfo, connectCompileOptions, left, right_v(idx), context_mod)
+ } catch {
+ case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
+ }
+ }
+ }
// Handle Records defined in Chisel._ code (change to NotStrict)
case (left_r: Record, right_r: Record) => (left_r.compileOptions, right_r.compileOptions) match {
case (ExplicitCompileOptions.NotStrict, _) =>
@@ -89,9 +113,40 @@ object BiConnect {
case _ => recordConnect(sourceInfo, connectCompileOptions, left_r, right_r, context_mod)
}
+ // Handle Records connected to DontCare (change to NotStrict)
+ case (left_r: Record, DontCare) =>
+ left_r.compileOptions match {
+ case ExplicitCompileOptions.NotStrict =>
+ left.bulkConnect(right)(sourceInfo, ExplicitCompileOptions.NotStrict)
+ case _ =>
+ // For each field in left, descend with right
+ for ((field, left_sub) <- left_r.elements) {
+ try {
+ connect(sourceInfo, connectCompileOptions, left_sub, right, context_mod)
+ } catch {
+ case BiConnectException(message) => throw BiConnectException(s".$field$message")
+ }
+ }
+ }
+ case (DontCare, right_r: Record) =>
+ right_r.compileOptions match {
+ case ExplicitCompileOptions.NotStrict =>
+ left.bulkConnect(right)(sourceInfo, ExplicitCompileOptions.NotStrict)
+ case _ =>
+ // For each field in left, descend with right
+ for ((field, right_sub) <- right_r.elements) {
+ try {
+ connect(sourceInfo, connectCompileOptions, left, right_sub, context_mod)
+ } catch {
+ case BiConnectException(message) => throw BiConnectException(s".$field$message")
+ }
+ }
+ }
+
// Left and right are different subtypes of Data so fail
case (left, right) => throw MismatchedException(left.toString, right.toString)
}
+ }
// Do connection of two Records
def recordConnect(sourceInfo: SourceInfo,
@@ -128,11 +183,25 @@ object BiConnect {
// These functions (finally) issue the connection operation
// Issue with right as sink, left as source
private def issueConnectL2R(left: Element, right: Element)(implicit sourceInfo: SourceInfo): Unit = {
- pushCommand(Connect(sourceInfo, right.lref, left.ref))
+ // Source and sink are ambiguous in the case of a Bi/Bulk Connect (<>).
+ // If either is a DontCareBinding, just issue a DefInvalid for the other,
+ // otherwise, issue a Connect.
+ (left.binding, right.binding) match {
+ case (lb: DontCareBinding, _) => pushCommand(DefInvalid(sourceInfo, right.lref))
+ case (_, rb: DontCareBinding) => pushCommand(DefInvalid(sourceInfo, left.lref))
+ case (_, _) => pushCommand(Connect(sourceInfo, right.lref, left.ref))
+ }
}
// Issue with left as sink, right as source
private def issueConnectR2L(left: Element, right: Element)(implicit sourceInfo: SourceInfo): Unit = {
- pushCommand(Connect(sourceInfo, left.lref, right.ref))
+ // Source and sink are ambiguous in the case of a Bi/Bulk Connect (<>).
+ // If either is a DontCareBinding, just issue a DefInvalid for the other,
+ // otherwise, issue a Connect.
+ (left.binding, right.binding) match {
+ case (lb: DontCareBinding, _) => pushCommand(DefInvalid(sourceInfo, right.lref))
+ case (_, rb: DontCareBinding) => pushCommand(DefInvalid(sourceInfo, left.lref))
+ case (_, _) => pushCommand(Connect(sourceInfo, left.lref, right.ref))
+ }
}
// This function checks if element-level connection operation allowed.