summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorJack Koenig2021-07-01 20:02:03 -0700
committerGitHub2021-07-01 20:02:03 -0700
commit4b7499f7c6287c696111bd7c6ee060f33f667419 (patch)
tree017e3eb957b38da9ef098d612eea6da61604845e /core/src/main
parent1e40c7e2a2fd227c752e4e4dc29925004f790f7d (diff)
parentbfb77d4cc1163e34cc54ce856214a0181b2cb029 (diff)
Merge pull request #1999 from chipsalliance/fix-chiselenum-warnings
Fix ChiselEnum warnings and use Logger for warnings instead of println
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/scala/chisel3/StrongEnum.scala34
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala2
-rw-r--r--core/src/main/scala/chisel3/internal/Error.scala25
3 files changed, 44 insertions, 17 deletions
diff --git a/core/src/main/scala/chisel3/StrongEnum.scala b/core/src/main/scala/chisel3/StrongEnum.scala
index 7d328eb7..1d0e04d3 100644
--- a/core/src/main/scala/chisel3/StrongEnum.scala
+++ b/core/src/main/scala/chisel3/StrongEnum.scala
@@ -131,7 +131,7 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea
if (litOption.isDefined) {
true.B
} else {
- factory.all.map(this === _).reduce(_ || _)
+ if (factory.isTotal) true.B else factory.all.map(this === _).reduce(_ || _)
}
}
@@ -233,6 +233,12 @@ abstract class EnumFactory {
private[chisel3] val enumTypeName = getClass.getName.init
+ // Do all bitvectors of this Enum's width represent legal states?
+ private[chisel3] def isTotal: Boolean = {
+ (this.getWidth < 31) && // guard against Integer overflow
+ (enumRecords.size == (1 << this.getWidth))
+ }
+
private[chisel3] def globalAnnotation: EnumDefChiselAnnotation =
EnumDefChiselAnnotation(enumTypeName, (enumNames, enumValues).zipped.toMap)
@@ -277,7 +283,7 @@ abstract class EnumFactory {
def apply(): Type = new Type
- def apply(n: UInt)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = {
+ private def castImpl(n: UInt, warn: Boolean)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = {
if (n.litOption.isDefined) {
enumInstances.find(_.litValue == n.litValue) match {
case Some(result) => result
@@ -288,8 +294,9 @@ abstract class EnumFactory {
} else if (n.getWidth > this.getWidth) {
throwException(s"The UInt being cast to $enumTypeName is wider than $enumTypeName's width ($getWidth)")
} else {
- Builder.warning(s"Casting non-literal UInt to $enumTypeName. You can check that its value is legal by calling isValid")
-
+ if (warn && !this.isTotal) {
+ Builder.warning(s"Casting non-literal UInt to $enumTypeName. You can use $enumTypeName.safe to cast without this warning.")
+ }
val glue = Wire(new UnsafeEnum(width))
glue := n
val result = Wire(new Type)
@@ -297,6 +304,25 @@ abstract class EnumFactory {
result
}
}
+
+ /** Cast an [[UInt]] to the type of this Enum
+ *
+ * @note will give a Chisel elaboration time warning if the argument could hit invalid states
+ * @param n the UInt to cast
+ * @return the equivalent Enum to the value of the cast UInt
+ */
+ def apply(n: UInt)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = castImpl(n, warn = true)
+
+ /** Safely cast an [[UInt]] to the type of this Enum
+ *
+ * @param n the UInt to cast
+ * @return the equivalent Enum to the value of the cast UInt and a Bool indicating if the
+ * Enum is valid
+ */
+ def safe(n: UInt)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): (Type, Bool) = {
+ val t = castImpl(n, warn = false)
+ (t, t.isValid)
+ }
}
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index 35c4bdf9..fef12093 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -652,7 +652,7 @@ private[chisel3] object Builder extends LazyLogging {
logger.warn("Elaborating design...")
val mod = f
mod.forceName(None, mod.name, globalNamespace)
- errors.checkpoint()
+ errors.checkpoint(logger)
logger.warn("Done elaborating.")
(Circuit(components.last.name, components.toSeq, annotations.toSeq), mod)
diff --git a/core/src/main/scala/chisel3/internal/Error.scala b/core/src/main/scala/chisel3/internal/Error.scala
index 454be360..d6e0c0e6 100644
--- a/core/src/main/scala/chisel3/internal/Error.scala
+++ b/core/src/main/scala/chisel3/internal/Error.scala
@@ -4,6 +4,7 @@ package chisel3.internal
import scala.annotation.tailrec
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
+import _root_.logger.Logger
object ExceptionHelpers {
@@ -184,31 +185,31 @@ private[chisel3] class ErrorLog {
}
/** Throw an exception if any errors have yet occurred. */
- def checkpoint(): Unit = {
+ def checkpoint(logger: Logger): Unit = {
deprecations.foreach { case ((message, sourceLoc), count) =>
- println(s"${ErrorLog.depTag} $sourceLoc ($count calls): $message")
+ logger.warn(s"${ErrorLog.depTag} $sourceLoc ($count calls): $message")
}
- errors foreach println
+ errors.foreach(e => logger.error(e.toString))
if (!deprecations.isEmpty) {
- println(s"${ErrorLog.warnTag} ${Console.YELLOW}There were ${deprecations.size} deprecated function(s) used." +
+ logger.warn(s"${ErrorLog.warnTag} ${Console.YELLOW}There were ${deprecations.size} deprecated function(s) used." +
s" These may stop compiling in a future release - you are encouraged to fix these issues.${Console.RESET}")
- println(s"${ErrorLog.warnTag} Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:")
- println(s"${ErrorLog.warnTag} In the sbt interactive console, enter:")
- println(s"""${ErrorLog.warnTag} set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")""")
- println(s"${ErrorLog.warnTag} or, in your build.sbt, add the line:")
- println(s"""${ErrorLog.warnTag} scalacOptions := Seq("-unchecked", "-deprecation")""")
+ logger.warn(s"${ErrorLog.warnTag} Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:")
+ logger.warn(s"${ErrorLog.warnTag} In the sbt interactive console, enter:")
+ logger.warn(s"""${ErrorLog.warnTag} set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")""")
+ logger.warn(s"${ErrorLog.warnTag} or, in your build.sbt, add the line:")
+ logger.warn(s"""${ErrorLog.warnTag} scalacOptions := Seq("-unchecked", "-deprecation")""")
}
val allErrors = errors.filter(_.isFatal)
val allWarnings = errors.filter(!_.isFatal)
if (!allWarnings.isEmpty && !allErrors.isEmpty) {
- println(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} and ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.")
+ logger.warn(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} and ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.")
} else if (!allWarnings.isEmpty) {
- println(s"${ErrorLog.warnTag} There were ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.")
+ logger.warn(s"${ErrorLog.warnTag} There were ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.")
} else if (!allErrors.isEmpty) {
- println(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} during hardware elaboration.")
+ logger.warn(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} during hardware elaboration.")
}
if (!allErrors.isEmpty) {