summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala2
-rw-r--r--core/src/main/scala/chisel3/internal/Builder.scala8
-rw-r--r--core/src/main/scala/chisel3/internal/Error.scala9
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala7
-rw-r--r--src/main/scala/chisel3/stage/ChiselAnnotations.scala18
-rw-r--r--src/main/scala/chisel3/stage/ChiselCli.scala1
-rw-r--r--src/main/scala/chisel3/stage/ChiselOptions.scala3
-rw-r--r--src/main/scala/chisel3/stage/package.scala1
-rw-r--r--src/main/scala/chisel3/stage/phases/Elaborate.scala7
-rw-r--r--src/test/scala/chiselTests/WarningSpec.scala37
10 files changed, 69 insertions, 24 deletions
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
index 36bf6f87..99eacc7d 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
@@ -103,7 +103,7 @@ object Definition extends SourceInfoDoc {
): Definition[T] = {
val dynamicContext = {
val context = Builder.captureContext()
- new DynamicContext(Nil, context.throwOnFirstError, context.warnReflectiveNaming)
+ new DynamicContext(Nil, context.throwOnFirstError, context.warnReflectiveNaming, context.warningsAsErrors)
}
Builder.globalNamespace.copyTo(dynamicContext.globalNamespace)
dynamicContext.inDefinition = true
diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala
index b2c98309..75d08f92 100644
--- a/core/src/main/scala/chisel3/internal/Builder.scala
+++ b/core/src/main/scala/chisel3/internal/Builder.scala
@@ -244,7 +244,8 @@ private[chisel3] trait HasId extends InstanceId {
// These accesses occur after Chisel elaboration so we cannot use the normal
// Builder.deprecated mechanism, we have to create our own one off ErrorLog and print the
// warning right away.
- val errors = new ErrorLog
+ // It's especially bad because --warnings-as-errors does not work with these warnings
+ val errors = new ErrorLog(false)
val logger = new _root_.logger.Logger(this.getClass.getName)
val msg = "Accessing the .instanceName or .toTarget of non-hardware Data is deprecated. " +
"This will become an error in Chisel 3.6."
@@ -376,7 +377,8 @@ private[chisel3] class ChiselContext() {
private[chisel3] class DynamicContext(
val annotationSeq: AnnotationSeq,
val throwOnFirstError: Boolean,
- val warnReflectiveNaming: Boolean) {
+ val warnReflectiveNaming: Boolean,
+ val warningsAsErrors: Boolean) {
val importDefinitionAnnos = annotationSeq.collect { case a: ImportDefinitionAnnotation[_] => a }
// Map holding the actual names of extModules
@@ -433,7 +435,7 @@ private[chisel3] class DynamicContext(
var whenStack: List[WhenContext] = Nil
var currentClock: Option[Clock] = None
var currentReset: Option[Reset] = None
- val errors = new ErrorLog
+ val errors = new ErrorLog(warningsAsErrors)
val namingStack = new NamingStack
// Used to indicate if this is the top-level module of full elaboration, or from a Definition
diff --git a/core/src/main/scala/chisel3/internal/Error.scala b/core/src/main/scala/chisel3/internal/Error.scala
index 98db7109..da968d2a 100644
--- a/core/src/main/scala/chisel3/internal/Error.scala
+++ b/core/src/main/scala/chisel3/internal/Error.scala
@@ -176,7 +176,7 @@ private[chisel3] object ErrorLog {
val errTag = s"[${Console.RED}error${Console.RESET}]"
}
-private[chisel3] class ErrorLog {
+private[chisel3] class ErrorLog(warningsAsErrors: Boolean) {
def getLoc(loc: Option[StackTraceElement]): String = {
loc match {
case Some(elt: StackTraceElement) => s"${elt.getFileName}:${elt.getLineNumber}"
@@ -190,17 +190,20 @@ private[chisel3] class ErrorLog {
errors += (((m, getLoc(loc)), new Error(m, loc)))
}
+ private def warn(m: => String, loc: Option[StackTraceElement]): LogEntry =
+ if (warningsAsErrors) new Error(m, loc) else new Warning(m, loc)
+
/** Log a warning message */
def warning(m: => String): Unit = {
val loc = getUserLineNumber
- errors += (((m, getLoc(loc)), new Warning(m, loc)))
+ errors += (((m, getLoc(loc)), warn(m, loc)))
}
/** Log a warning message without a source locator. This is used when the
* locator wouldn't be helpful (e.g., due to lazy values).
*/
def warningNoLoc(m: => String): Unit =
- errors += (((m, ""), new Warning(m, None)))
+ errors += (((m, ""), warn(m, None)))
/** Emit an informational message */
@deprecated("This method will be removed in 3.5", "3.4")
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
index 087bdae2..ecce19e1 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
@@ -59,7 +59,12 @@ abstract class InjectorAspect[T <: RawModule, M <: RawModule](
RunFirrtlTransformAnnotation(new InjectingTransform) +: modules.map { module =>
val chiselOptions = view[ChiselOptions](annotationsInAspect)
val dynamicContext =
- new DynamicContext(annotationsInAspect, chiselOptions.throwOnFirstError, chiselOptions.warnReflectiveNaming)
+ new DynamicContext(
+ annotationsInAspect,
+ chiselOptions.throwOnFirstError,
+ chiselOptions.warnReflectiveNaming,
+ chiselOptions.warningsAsErrors
+ )
// Add existing module names into the namespace. If injection logic instantiates new modules
// which would share the same name, they will get uniquified accordingly
moduleNames.foreach { n =>
diff --git a/src/main/scala/chisel3/stage/ChiselAnnotations.scala b/src/main/scala/chisel3/stage/ChiselAnnotations.scala
index eda05a7d..f65fabdc 100644
--- a/src/main/scala/chisel3/stage/ChiselAnnotations.scala
+++ b/src/main/scala/chisel3/stage/ChiselAnnotations.scala
@@ -79,6 +79,24 @@ case object ThrowOnFirstErrorAnnotation
}
+/** When enabled, warnings will be treated as errors.
+ */
+case object WarningsAsErrorsAnnotation
+ extends NoTargetAnnotation
+ with ChiselOption
+ with HasShellOptions
+ with Unserializable {
+
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "warnings-as-errors",
+ toAnnotationSeq = _ => Seq(WarningsAsErrorsAnnotation),
+ helpText = "Treat warnings as errors"
+ )
+ )
+
+}
+
/** Warn when reflective naming changes names of signals */
case object WarnReflectiveNamingAnnotation
extends NoTargetAnnotation
diff --git a/src/main/scala/chisel3/stage/ChiselCli.scala b/src/main/scala/chisel3/stage/ChiselCli.scala
index 8c5eb79a..60e30152 100644
--- a/src/main/scala/chisel3/stage/ChiselCli.scala
+++ b/src/main/scala/chisel3/stage/ChiselCli.scala
@@ -10,6 +10,7 @@ trait ChiselCli { this: Shell =>
NoRunFirrtlCompilerAnnotation,
PrintFullStackTraceAnnotation,
ThrowOnFirstErrorAnnotation,
+ WarningsAsErrorsAnnotation,
WarnReflectiveNamingAnnotation,
ChiselOutputFileAnnotation,
ChiselGeneratorAnnotation
diff --git a/src/main/scala/chisel3/stage/ChiselOptions.scala b/src/main/scala/chisel3/stage/ChiselOptions.scala
index a03f3d7b..42a0ce68 100644
--- a/src/main/scala/chisel3/stage/ChiselOptions.scala
+++ b/src/main/scala/chisel3/stage/ChiselOptions.scala
@@ -9,6 +9,7 @@ class ChiselOptions private[stage] (
val printFullStackTrace: Boolean = false,
val throwOnFirstError: Boolean = false,
val warnReflectiveNaming: Boolean = false,
+ val warningsAsErrors: Boolean = false,
val outputFile: Option[String] = None,
val chiselCircuit: Option[Circuit] = None) {
@@ -17,6 +18,7 @@ class ChiselOptions private[stage] (
printFullStackTrace: Boolean = printFullStackTrace,
throwOnFirstError: Boolean = throwOnFirstError,
warnReflectiveNaming: Boolean = warnReflectiveNaming,
+ warningsAsErrors: Boolean = warningsAsErrors,
outputFile: Option[String] = outputFile,
chiselCircuit: Option[Circuit] = chiselCircuit
): ChiselOptions = {
@@ -26,6 +28,7 @@ class ChiselOptions private[stage] (
printFullStackTrace = printFullStackTrace,
throwOnFirstError = throwOnFirstError,
warnReflectiveNaming = warnReflectiveNaming,
+ warningsAsErrors = warningsAsErrors,
outputFile = outputFile,
chiselCircuit = chiselCircuit
)
diff --git a/src/main/scala/chisel3/stage/package.scala b/src/main/scala/chisel3/stage/package.scala
index 10c8c524..c76dac17 100644
--- a/src/main/scala/chisel3/stage/package.scala
+++ b/src/main/scala/chisel3/stage/package.scala
@@ -19,6 +19,7 @@ package object stage {
case PrintFullStackTraceAnnotation => c.copy(printFullStackTrace = true)
case ThrowOnFirstErrorAnnotation => c.copy(throwOnFirstError = true)
case WarnReflectiveNamingAnnotation => c.copy(warnReflectiveNaming = true)
+ case WarningsAsErrorsAnnotation => c.copy(warningsAsErrors = true)
case ChiselOutputFileAnnotation(f) => c.copy(outputFile = Some(f))
case ChiselCircuitAnnotation(a) => c.copy(chiselCircuit = Some(a))
}
diff --git a/src/main/scala/chisel3/stage/phases/Elaborate.scala b/src/main/scala/chisel3/stage/phases/Elaborate.scala
index ba29e5f2..a3fc4990 100644
--- a/src/main/scala/chisel3/stage/phases/Elaborate.scala
+++ b/src/main/scala/chisel3/stage/phases/Elaborate.scala
@@ -30,7 +30,12 @@ class Elaborate extends Phase {
val chiselOptions = view[ChiselOptions](annotations)
try {
val context =
- new DynamicContext(annotations, chiselOptions.throwOnFirstError, chiselOptions.warnReflectiveNaming)
+ new DynamicContext(
+ annotations,
+ chiselOptions.throwOnFirstError,
+ chiselOptions.warnReflectiveNaming,
+ chiselOptions.warningsAsErrors
+ )
val (circuit, dut) =
Builder.build(Module(gen()), context)
Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut))
diff --git a/src/test/scala/chiselTests/WarningSpec.scala b/src/test/scala/chiselTests/WarningSpec.scala
index bf3830d6..1cef1ffc 100644
--- a/src/test/scala/chiselTests/WarningSpec.scala
+++ b/src/test/scala/chiselTests/WarningSpec.scala
@@ -4,32 +4,39 @@ package chiselTests
import chisel3._
import chisel3.util._
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
+import chisel3.stage.ChiselStage
import chisel3.experimental.ChiselEnum
import chisel3.experimental.EnumType
-import chiselTests.ChiselFlatSpec
class WarningSpec extends ChiselFlatSpec with Utils {
behavior.of("Warnings")
- "Warnings" should "be de-duplicated" in {
- object MyEnum extends ChiselEnum {
- val e0, e1, e2 = Value
- }
+ object MyEnum extends ChiselEnum {
+ val e0, e1, e2 = Value
+ }
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out1 = IO(Output(MyEnum()))
- val out2 = IO(Output(MyEnum()))
- def func(out: EnumType): Unit = {
- out := MyEnum(in)
- }
- func(out1)
- func(out2)
+ class MyModule extends Module {
+ val in = IO(Input(UInt(2.W)))
+ val out1 = IO(Output(MyEnum()))
+ val out2 = IO(Output(MyEnum()))
+ def func(out: EnumType): Unit = {
+ out := MyEnum(in)
}
+ func(out1)
+ func(out2)
+ }
+
+ "Warnings" should "be de-duplicated" in {
val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
def countSubstring(s: String, sub: String) =
s.sliding(sub.length).count(_ == sub)
countSubstring(log, "Casting non-literal UInt") should be(1)
}
+
+ "Warnings" should "be treated as errors with warningsAsErrors" in {
+ a[ChiselException] should be thrownBy extractCause[ChiselException] {
+ val args = Array("--warnings-as-errors")
+ (new ChiselStage).emitChirrtl(new MyModule, args)
+ }
+ }
}