summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman2015-08-13 18:19:01 -0700
committerAndrew Waterman2015-08-13 18:19:42 -0700
commitac5bf6a4c953fe39fa97d77bc620c515dc9e1622 (patch)
tree07ae3cb60765446ba336527c41e571dfb6dca28d
parent178b3ed69661156f4c120c3b0be18d44a5d474af (diff)
Make error reporting reentrant
-rw-r--r--src/main/scala/Chisel/Builder.scala8
-rw-r--r--src/main/scala/Chisel/Core.scala12
-rw-r--r--src/main/scala/Chisel/Driver.scala8
-rw-r--r--src/main/scala/Chisel/Error.scala15
-rw-r--r--src/main/scala/Chisel/FP.scala1
-rw-r--r--src/main/scala/Chisel/Parameters.scala2
-rw-r--r--src/main/scala/Chisel/Utils.scala6
7 files changed, 25 insertions, 27 deletions
diff --git a/src/main/scala/Chisel/Builder.scala b/src/main/scala/Chisel/Builder.scala
index 79d1ab18..41fbb3b5 100644
--- a/src/main/scala/Chisel/Builder.scala
+++ b/src/main/scala/Chisel/Builder.scala
@@ -67,6 +67,7 @@ private class DynamicContext {
val components = ArrayBuffer[Component]()
var currentModule: Option[Module] = None
val parameterDump = new ParameterDump
+ val errors = new ErrorLog
}
private object Builder {
@@ -89,6 +90,9 @@ private object Builder {
cmd.id
}
+ def errors = dynamicContext.errors
+ def error(m: => String) = errors.error(m)
+
def getParams: Parameters = currentParamsVar.value
def paramsScope[T](p: Parameters)(body: => T): T = {
currentParamsVar.withValue(p)(body)
@@ -96,8 +100,12 @@ private object Builder {
def build[T <: Module](f: => T): Circuit = {
dynamicContextVar.withValue(Some(new DynamicContext)) {
+ errors.info("Elaborating design...")
val mod = f
mod.setRef(globalNamespace.name(mod.name))
+ errors.checkpoint()
+ errors.info("Done elaborating.")
+
Circuit(components.last.name, components, globalRefMap, parameterDump)
}
}
diff --git a/src/main/scala/Chisel/Core.scala b/src/main/scala/Chisel/Core.scala
index ccffbc96..cd271018 100644
--- a/src/main/scala/Chisel/Core.scala
+++ b/src/main/scala/Chisel/Core.scala
@@ -14,7 +14,7 @@ private object Literal {
case 'd' => 10
case 'o' => 8
case 'b' => 2
- case _ => ChiselError.error("Invalid base " + base); 2
+ case _ => Builder.error("Invalid base " + base); 2
}
def stringToVal(base: Char, x: String): BigInt =
@@ -277,7 +277,7 @@ object BitPat {
var mask = BigInt(0)
for (d <- x.tail) {
if (d != '_') {
- if (!"01?".contains(d)) ChiselError.error({"Literal: " + x + " contains illegal character: " + d})
+ if (!"01?".contains(d)) Builder.error({"Literal: " + x + " contains illegal character: " + d})
mask = (mask << 1) + (if (d == '?') 0 else 1)
bits = (bits << 1) + (if (d == '1') 1 else 0)
}
@@ -338,7 +338,7 @@ sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg:
final def apply(x: BigInt): Bool = {
if (x < 0)
- ChiselError.error(s"Negative bit indices are illegal (got $x)")
+ Builder.error(s"Negative bit indices are illegal (got $x)")
if (isLit()) Bool(((litValue() >> x.toInt) & 1) == 1)
else pushOp(DefPrim(Bool(), BitSelectOp, this.ref, ILit(x)))
}
@@ -349,7 +349,7 @@ sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg:
final def apply(x: Int, y: Int): UInt = {
if (x < y || y < 0)
- ChiselError.error(s"Invalid bit range ($x,$y)")
+ Builder.error(s"Invalid bit range ($x,$y)")
val w = x - y + 1
if (isLit()) UInt((litValue >> y) & ((BigInt(1) << w) - 1), w)
else pushOp(DefPrim(UInt(width = w), BitsExtractOp, this.ref, ILit(x), ILit(y)))
@@ -695,10 +695,10 @@ class Bundle extends Aggregate(NO_DIR) {
res.asInstanceOf[this.type]
} catch {
case npe: java.lang.reflect.InvocationTargetException if npe.getCause.isInstanceOf[java.lang.NullPointerException] =>
- ChiselError.error(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using an anonymous Bundle object that captures external state and hence is un-cloneTypeable")
+ Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using an anonymous Bundle object that captures external state and hence is un-cloneTypeable")
this
case npe: java.lang.reflect.InvocationTargetException =>
- ChiselError.error(s"Parameterized Bundle ${this.getClass} needs cloneType method")
+ Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method")
this
}
}
diff --git a/src/main/scala/Chisel/Driver.scala b/src/main/scala/Chisel/Driver.scala
index 682988f8..b1fa831c 100644
--- a/src/main/scala/Chisel/Driver.scala
+++ b/src/main/scala/Chisel/Driver.scala
@@ -81,11 +81,7 @@ object Driver extends FileSystemUtilities {
*/
private[Chisel] def elaborateWrappedModule[T <: Module](gen: () => T, p: Parameters, c: Option[ChiselConfig]) {
try {
- ChiselError.clear()
- ChiselError.info("Elaborating design...")
val ir = Builder.build(gen())
- ChiselError.info("Done elaborating.")
-
val name = c match {
case None => ir.name
case Some(config) => s"${ir.name}.$config"
@@ -94,8 +90,8 @@ object Driver extends FileSystemUtilities {
createOutputFile(s"$name.cst", p.getConstraints)
createOutputFile(s"$name.prm", ir.parameterDump.getDump)
createOutputFile(s"$name.fir", ir.emit)
- } finally {
- ChiselError.report
+ } catch {
+ case e: ChiselException => println(e.getMessage)
}
}
def elaborate[T <: Module](gen: () => T): Unit =
diff --git a/src/main/scala/Chisel/Error.scala b/src/main/scala/Chisel/Error.scala
index c5fe4796..622d51a3 100644
--- a/src/main/scala/Chisel/Error.scala
+++ b/src/main/scala/Chisel/Error.scala
@@ -38,15 +38,10 @@ private object throwException {
throw new ChiselException(s, t)
}
-/** This Singleton implements a log4j compatible interface.
- It is used through out the Chisel package to report errors and warnings
- detected at runtime.
- */
-private object ChiselError {
+/** Records and reports runtime errors and warnings. */
+private class ErrorLog {
def hasErrors = errors.exists(_.isFatal)
- def clear(): Unit = errors.clear
-
/** Log an error message */
def error(m: => String): Unit =
errors += new Error(m, getUserLineNumber)
@@ -57,7 +52,7 @@ private object ChiselError {
/** Emit an informational message */
def info(m: String): Unit =
- println(new Info(" [%2.3f] %s".format(elapsedTime/1e3, m), None))
+ println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None))
/** Prints error messages generated by Chisel at runtime. */
def report(): Unit = errors foreach println
@@ -65,7 +60,7 @@ private object ChiselError {
/** Throw an exception if any errors have yet occurred. */
def checkpoint(): Unit = if(hasErrors) {
import Console._
- throw new IllegalStateException(
+ throwException(errors.map(_ + "\n").reduce(_+_) +
UNDERLINED + "CODE HAS " + errors.filter(_.isFatal).length + RESET +
UNDERLINED + " " + RED + "ERRORS" + RESET +
UNDERLINED + " and " + errors.filterNot(_.isFatal).length + RESET +
@@ -100,7 +95,7 @@ private abstract class LogEntry(msg: => String, line: Option[StackTraceElement])
override def toString: String = line match {
case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}"
- case None => s"${format}: ${msg}"
+ case None => s"${format} ${msg}"
}
protected def tag(name: String, color: String): String =
diff --git a/src/main/scala/Chisel/FP.scala b/src/main/scala/Chisel/FP.scala
index 0bbb869d..8dcff65b 100644
--- a/src/main/scala/Chisel/FP.scala
+++ b/src/main/scala/Chisel/FP.scala
@@ -31,7 +31,6 @@
package Chisel
import Chisel._
import Builder.pushOp
-import ChiselError._
/// FLO
diff --git a/src/main/scala/Chisel/Parameters.scala b/src/main/scala/Chisel/Parameters.scala
index ca2bcebd..cc1fe0be 100644
--- a/src/main/scala/Chisel/Parameters.scala
+++ b/src/main/scala/Chisel/Parameters.scala
@@ -458,7 +458,7 @@ final class Parameters(
def constrain(gen:ViewSym=>Ex[Boolean]) = {
val g = gen(new ViewSym(_site()))
- if(!_world._eval(g)) ChiselError.error("Constraint failed: " + g.toString)
+ if(!_world._eval(g)) Builder.error("Constraint failed: " + g.toString)
_world._constrain(g)
}
diff --git a/src/main/scala/Chisel/Utils.scala b/src/main/scala/Chisel/Utils.scala
index be675da5..262d7c8e 100644
--- a/src/main/scala/Chisel/Utils.scala
+++ b/src/main/scala/Chisel/Utils.scala
@@ -143,9 +143,9 @@ class SwitchContext[T <: Bits](cond: T) {
}
object is { // Begin deprecation of non-type-parameterized is statements.
- def apply(v: Iterable[Bits])(block: => Unit) { ChiselError.error("The 'is' keyword may not be used outside of a switch.") }
- def apply(v: Bits)(block: => Unit) { ChiselError.error("The 'is' keyword may not be used outside of a switch.") }
- def apply(v: Bits, vr: Bits*)(block: => Unit) { ChiselError.error("The 'is' keyword may not be used outside of a switch.") }
+ def apply(v: Iterable[Bits])(block: => Unit) { Builder.error("The 'is' keyword may not be used outside of a switch.") }
+ def apply(v: Bits)(block: => Unit) { Builder.error("The 'is' keyword may not be used outside of a switch.") }
+ def apply(v: Bits, vr: Bits*)(block: => Unit) { Builder.error("The 'is' keyword may not be used outside of a switch.") }
}
object switch {