summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/internal
diff options
context:
space:
mode:
authorAditya Naik2021-12-09 11:19:27 -0800
committerGitHub2021-12-09 19:19:27 +0000
commit3f21bbb52363c3105f6a0ff961fa7a411dd0c7ab (patch)
tree51091d93308f2f6f781e47128b1c6f26af2898f2 /core/src/main/scala/chisel3/internal
parent849d4a0b7f6f7ea056c5280b9d319dadf5225022 (diff)
Better MonoConnect error messages (#2248)
Co-authored-by: Megan Wachs <megan@sifive.com>
Diffstat (limited to 'core/src/main/scala/chisel3/internal')
-rw-r--r--core/src/main/scala/chisel3/internal/MonoConnect.scala72
1 files changed, 37 insertions, 35 deletions
diff --git a/core/src/main/scala/chisel3/internal/MonoConnect.scala b/core/src/main/scala/chisel3/internal/MonoConnect.scala
index 5cbab329..6173fc91 100644
--- a/core/src/main/scala/chisel3/internal/MonoConnect.scala
+++ b/core/src/main/scala/chisel3/internal/MonoConnect.scala
@@ -36,33 +36,35 @@ import chisel3.internal.sourceinfo.SourceInfo
*/
private[chisel3] object MonoConnect {
+ def formatName(data: Data) = s"""${data.earlyName} in ${data.parentNameOpt.getOrElse("(unknown)")}"""
+
// These are all the possible exceptions that can be thrown.
// These are from element-level connection
- def UnreadableSourceException =
- MonoConnectException(": Source is unreadable from current module.")
- def UnwritableSinkException =
- MonoConnectException(": Sink is unwriteable by current module.")
- def SourceEscapedWhenScopeException =
- MonoConnectException(": Source has escaped the scope of the when in which it was constructed.")
- def SinkEscapedWhenScopeException =
- MonoConnectException(": Sink has escaped the scope of the when in which it was constructed.")
+ def UnreadableSourceException(sink: Data, source: Data) =
+ MonoConnectException(s"""${formatName(source)} cannot be read from module ${sink.parentNameOpt.getOrElse("(unknown)")}.""")
+ def UnwritableSinkException(sink: Data, source: Data) =
+ MonoConnectException(s"""${formatName(sink)} cannot be written from module ${source.parentNameOpt.getOrElse("(unknown)")}.""")
+ def SourceEscapedWhenScopeException(source: Data) =
+ MonoConnectException(s"Source ${formatName(source)} has escaped the scope of the when in which it was constructed.")
+ def SinkEscapedWhenScopeException(sink: Data) =
+ MonoConnectException(s"Sink ${formatName(sink)} has escaped the scope of the when in which it was constructed.")
def UnknownRelationException =
- MonoConnectException(": Sink or source unavailable to current module.")
+ MonoConnectException("Sink or source unavailable to current module.")
// These are when recursing down aggregate types
def MismatchedVecException =
- MonoConnectException(": Sink and Source are different length Vecs.")
+ MonoConnectException("Sink and Source are different length Vecs.")
def MissingFieldException(field: String) =
- MonoConnectException(s": Source Record missing field ($field).")
- def MismatchedException(sink: String, source: String) =
- MonoConnectException(s": Sink ($sink) and Source ($source) have different types.")
+ MonoConnectException(s"Source Record missing field ($field).")
+ def MismatchedException(sink: Data, source: Data) =
+ MonoConnectException(s"Sink (${sink.cloneType.toString}) and Source (${source.cloneType.toString}) have different types.")
def DontCareCantBeSink =
- MonoConnectException(": DontCare cannot be a connection sink (LHS)")
- def AnalogCantBeMonoSink =
- MonoConnectException(": Analog cannot participate in a mono connection (sink - LHS)")
- def AnalogCantBeMonoSource =
- MonoConnectException(": Analog cannot participate in a mono connection (source - RHS)")
- def AnalogMonoConnectionException =
- MonoConnectException(": Analog cannot participate in a mono connection (source and sink)")
+ MonoConnectException("DontCare cannot be a connection sink")
+ def AnalogCantBeMonoSink(sink: Data) =
+ MonoConnectException(s"Sink ${formatName(sink)} of type Analog cannot participate in a mono connection (:=)")
+ def AnalogCantBeMonoSource(source: Data) =
+ MonoConnectException(s"Source ${formatName(source)} of type Analog cannot participate in a mono connection (:=)")
+ def AnalogMonoConnectionException(source: Data, sink: Data) =
+ MonoConnectException(s"Source ${formatName(source)} and sink ${formatName(sink)} of type Analog cannot participate in a mono connection (:=)")
def checkWhenVisibility(x: Data): Boolean = {
x.topBinding match {
@@ -169,13 +171,13 @@ private[chisel3] object MonoConnect {
// DontCare as a sink is illegal.
case (DontCare, _) => throw DontCareCantBeSink
// Analog is illegal in mono connections.
- case (_: Analog, _:Analog) => throw AnalogMonoConnectionException
+ case (_: Analog, _:Analog) => throw AnalogMonoConnectionException(source, sink)
// Analog is illegal in mono connections.
- case (_: Analog, _) => throw AnalogCantBeMonoSink
+ case (_: Analog, _) => throw AnalogCantBeMonoSink(sink)
// Analog is illegal in mono connections.
- case (_, _: Analog) => throw AnalogCantBeMonoSource
+ case (_, _: Analog) => throw AnalogCantBeMonoSource(source)
// Sink and source are different subtypes of data so fail
- case (sink, source) => throw MismatchedException(sink.toString, source.toString)
+ case (sink, source) => throw MismatchedException(sink, source)
}
// This function (finally) issues the connection operation
@@ -196,7 +198,7 @@ private[chisel3] object MonoConnect {
val source = reify(_source)
// If source has no location, assume in context module
// This can occur if is a literal, unbound will error previously
- val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException)
+ val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException(sink, source))
val source_mod: BaseModule = source.topBinding.location.getOrElse(context_mod)
val sink_parent = Builder.retrieveParent(sink_mod, context_mod).getOrElse(None)
@@ -206,11 +208,11 @@ private[chisel3] object MonoConnect {
val source_direction = BindingDirection.from(source.topBinding, source.direction)
if (!checkWhenVisibility(sink)) {
- throw SinkEscapedWhenScopeException
+ throw SinkEscapedWhenScopeException(sink)
}
if (!checkWhenVisibility(source)) {
- throw SourceEscapedWhenScopeException
+ throw SourceEscapedWhenScopeException(source)
}
// CASE: Context is same module that both left node and right node are in
@@ -220,7 +222,7 @@ private[chisel3] object MonoConnect {
// CURRENT MOD CURRENT MOD
case (Output, _) => issueConnect(sink, source)
case (Internal, _) => issueConnect(sink, source)
- case (Input, _) => throw UnwritableSinkException
+ case (Input, _) => throw UnwritableSinkException(sink, source)
}
}
@@ -238,11 +240,11 @@ private[chisel3] object MonoConnect {
if (!(connectCompileOptions.dontAssumeDirectionality)) {
issueConnect(sink, source)
} else {
- throw UnreadableSourceException
+ throw UnreadableSourceException(sink, source)
}
}
case (Input, Output) if (!(connectCompileOptions.dontTryConnectionsSwapped)) => issueConnect(source, sink)
- case (Input, _) => throw UnwritableSinkException
+ case (Input, _) => throw UnwritableSinkException(sink, source)
}
}
@@ -253,8 +255,8 @@ private[chisel3] object MonoConnect {
// SINK SOURCE
// CHILD MOD CURRENT MOD
case (Input, _) => issueConnect(sink, source)
- case (Output, _) => throw UnwritableSinkException
- case (Internal, _) => throw UnwritableSinkException
+ case (Output, _) => throw UnwritableSinkException(sink, source)
+ case (Internal, _) => throw UnwritableSinkException(sink, source)
}
}
@@ -268,15 +270,15 @@ private[chisel3] object MonoConnect {
// CHILD MOD CHILD MOD
case (Input, Input) => issueConnect(sink, source)
case (Input, Output) => issueConnect(sink, source)
- case (Output, _) => throw UnwritableSinkException
+ case (Output, _) => throw UnwritableSinkException(sink, source)
case (_, Internal) => {
if (!(connectCompileOptions.dontAssumeDirectionality)) {
issueConnect(sink, source)
} else {
- throw UnreadableSourceException
+ throw UnreadableSourceException(sink, source)
}
}
- case (Internal, _) => throw UnwritableSinkException
+ case (Internal, _) => throw UnwritableSinkException(sink, source)
}
}