diff options
| author | Andrew Waterman | 2015-08-13 18:19:01 -0700 |
|---|---|---|
| committer | Andrew Waterman | 2015-08-13 18:19:42 -0700 |
| commit | ac5bf6a4c953fe39fa97d77bc620c515dc9e1622 (patch) | |
| tree | 07ae3cb60765446ba336527c41e571dfb6dca28d /src | |
| parent | 178b3ed69661156f4c120c3b0be18d44a5d474af (diff) | |
Make error reporting reentrant
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/Chisel/Builder.scala | 8 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Core.scala | 12 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Driver.scala | 8 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Error.scala | 15 | ||||
| -rw-r--r-- | src/main/scala/Chisel/FP.scala | 1 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Parameters.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Utils.scala | 6 |
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 { |
