summaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala6
-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.scala5
-rw-r--r--src/main/scala/chisel3/stage/phases/Elaborate.scala14
-rw-r--r--src/main/scala/chisel3/util/Bitwise.scala2
-rw-r--r--src/main/scala/chisel3/util/GrayCode.scala24
-rw-r--r--src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala11
-rw-r--r--src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala49
10 files changed, 106 insertions, 27 deletions
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
index abe208cf..ba873c23 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
@@ -6,9 +6,10 @@ import chisel3.{withClockAndReset, Module, ModuleAspect, RawModule}
import chisel3.aop._
import chisel3.internal.{Builder, DynamicContext}
import chisel3.internal.firrtl.DefModule
-import chisel3.stage.DesignAnnotation
+import chisel3.stage.{ChiselOptions, DesignAnnotation}
import firrtl.annotations.ModuleTarget
import firrtl.stage.RunFirrtlTransformAnnotation
+import firrtl.options.Viewer.view
import firrtl.{ir, _}
import scala.collection.mutable
@@ -56,7 +57,8 @@ abstract class InjectorAspect[T <: RawModule, M <: RawModule](
*/
final def toAnnotation(modules: Iterable[M], circuit: String, moduleNames: Seq[String]): AnnotationSeq = {
RunFirrtlTransformAnnotation(new InjectingTransform) +: modules.map { module =>
- val dynamicContext = new DynamicContext(annotationsInAspect)
+ val chiselOptions = view[ChiselOptions](annotationsInAspect)
+ val dynamicContext = new DynamicContext(annotationsInAspect, chiselOptions.throwOnFirstError)
// 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 c5811813..e046319d 100644
--- a/src/main/scala/chisel3/stage/ChiselAnnotations.scala
+++ b/src/main/scala/chisel3/stage/ChiselAnnotations.scala
@@ -61,6 +61,24 @@ case object PrintFullStackTraceAnnotation
}
+/** On recoverable errors, this will cause Chisel to throw an exception instead of continuing.
+ */
+case object ThrowOnFirstErrorAnnotation
+ extends NoTargetAnnotation
+ with ChiselOption
+ with HasShellOptions
+ with Unserializable {
+
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "throw-on-first-error",
+ toAnnotationSeq = _ => Seq(ThrowOnFirstErrorAnnotation),
+ helpText = "Throw an exception on the first error instead of continuing"
+ )
+ )
+
+}
+
/** An [[firrtl.annotations.Annotation]] storing a function that returns a Chisel module
* @param gen a generator function
*/
diff --git a/src/main/scala/chisel3/stage/ChiselCli.scala b/src/main/scala/chisel3/stage/ChiselCli.scala
index 26b032bf..f38bf50c 100644
--- a/src/main/scala/chisel3/stage/ChiselCli.scala
+++ b/src/main/scala/chisel3/stage/ChiselCli.scala
@@ -9,6 +9,7 @@ trait ChiselCli { this: Shell =>
Seq(
NoRunFirrtlCompilerAnnotation,
PrintFullStackTraceAnnotation,
+ ThrowOnFirstErrorAnnotation,
ChiselOutputFileAnnotation,
ChiselGeneratorAnnotation
)
diff --git a/src/main/scala/chisel3/stage/ChiselOptions.scala b/src/main/scala/chisel3/stage/ChiselOptions.scala
index ed4d0a2f..7e4305fa 100644
--- a/src/main/scala/chisel3/stage/ChiselOptions.scala
+++ b/src/main/scala/chisel3/stage/ChiselOptions.scala
@@ -7,12 +7,14 @@ import chisel3.internal.firrtl.Circuit
class ChiselOptions private[stage] (
val runFirrtlCompiler: Boolean = true,
val printFullStackTrace: Boolean = false,
+ val throwOnFirstError: Boolean = false,
val outputFile: Option[String] = None,
val chiselCircuit: Option[Circuit] = None) {
private[stage] def copy(
runFirrtlCompiler: Boolean = runFirrtlCompiler,
printFullStackTrace: Boolean = printFullStackTrace,
+ throwOnFirstError: Boolean = throwOnFirstError,
outputFile: Option[String] = outputFile,
chiselCircuit: Option[Circuit] = chiselCircuit
): ChiselOptions = {
@@ -20,6 +22,7 @@ class ChiselOptions private[stage] (
new ChiselOptions(
runFirrtlCompiler = runFirrtlCompiler,
printFullStackTrace = printFullStackTrace,
+ throwOnFirstError = throwOnFirstError,
outputFile = outputFile,
chiselCircuit = chiselCircuit
)
diff --git a/src/main/scala/chisel3/stage/package.scala b/src/main/scala/chisel3/stage/package.scala
index bf03e2df..b1064c05 100644
--- a/src/main/scala/chisel3/stage/package.scala
+++ b/src/main/scala/chisel3/stage/package.scala
@@ -15,8 +15,9 @@ package object stage {
def view(options: AnnotationSeq): ChiselOptions = options.collect { case a: ChiselOption => a }
.foldLeft(new ChiselOptions()) { (c, x) =>
x match {
- case _: NoRunFirrtlCompilerAnnotation.type => c.copy(runFirrtlCompiler = false)
- case _: PrintFullStackTraceAnnotation.type => c.copy(printFullStackTrace = true)
+ case NoRunFirrtlCompilerAnnotation => c.copy(runFirrtlCompiler = false)
+ case PrintFullStackTraceAnnotation => c.copy(printFullStackTrace = true)
+ case ThrowOnFirstErrorAnnotation => c.copy(throwOnFirstError = 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 2cfb3200..55331cb4 100644
--- a/src/main/scala/chisel3/stage/phases/Elaborate.scala
+++ b/src/main/scala/chisel3/stage/phases/Elaborate.scala
@@ -5,7 +5,13 @@ package chisel3.stage.phases
import chisel3.Module
import chisel3.internal.ExceptionHelpers.ThrowableHelpers
import chisel3.internal.{Builder, DynamicContext}
-import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselOptions, DesignAnnotation}
+import chisel3.stage.{
+ ChiselCircuitAnnotation,
+ ChiselGeneratorAnnotation,
+ ChiselOptions,
+ DesignAnnotation,
+ ThrowOnFirstErrorAnnotation
+}
import firrtl.AnnotationSeq
import firrtl.options.Phase
import firrtl.options.Viewer.view
@@ -21,14 +27,16 @@ class Elaborate extends Phase {
def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap {
case ChiselGeneratorAnnotation(gen) =>
+ val chiselOptions = view[ChiselOptions](annotations)
try {
- val (circuit, dut) = Builder.build(Module(gen()), new DynamicContext(annotations))
+ val (circuit, dut) =
+ Builder.build(Module(gen()), new DynamicContext(annotations, chiselOptions.throwOnFirstError))
Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut))
} catch {
/* if any throwable comes back and we're in "stack trace trimming" mode, then print an error and trim the stack trace
*/
case scala.util.control.NonFatal(a) =>
- if (!view[ChiselOptions](annotations).printFullStackTrace) {
+ if (!chiselOptions.printFullStackTrace) {
a.trimStackTraceToUserCode()
}
throw (a)
diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala
index 0d8318bf..8abe3645 100644
--- a/src/main/scala/chisel3/util/Bitwise.scala
+++ b/src/main/scala/chisel3/util/Bitwise.scala
@@ -14,7 +14,7 @@ import chisel3._
* FillInterleaved(2, "b1 0 0 1".U) // equivalent to "b11 00 00 11".U
* FillInterleaved(2, myUIntWire) // dynamic interleaved fill
*
- * FillInterleaved(2, Seq(true.B, false.B, false.B, false.B)) // equivalent to "b11 00 00 00".U
+ * FillInterleaved(2, Seq(false.B, false.B, false.B, true.B)) // equivalent to "b11 00 00 00".U
* FillInterleaved(2, Seq(true.B, false.B, false.B, true.B)) // equivalent to "b11 00 00 11".U
* }}}
*/
diff --git a/src/main/scala/chisel3/util/GrayCode.scala b/src/main/scala/chisel3/util/GrayCode.scala
new file mode 100644
index 00000000..ef310ee9
--- /dev/null
+++ b/src/main/scala/chisel3/util/GrayCode.scala
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.util
+
+import chisel3._
+
+object BinaryToGray {
+
+ /** Turns a binary number into gray code. */
+ def apply(in: UInt): UInt = in ^ (in >> 1)
+}
+
+object GrayToBinary {
+
+ /** Inverts the [[BinaryToGray]] operation. */
+ def apply(in: UInt, width: Int): UInt = apply(in(width - 1, 0))
+
+ /** Inverts the [[BinaryToGray]] operation. */
+ def apply(in: UInt): UInt = if (in.getWidth < 2) { in }
+ else {
+ val bits = in.getWidth - 2 to 0 by -1
+ Cat(bits.scanLeft(in.head(1)) { case (prev, ii) => prev ^ in(ii) })
+ }
+}
diff --git a/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala b/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala
index de2f207b..86973e5b 100644
--- a/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala
+++ b/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala
@@ -57,11 +57,20 @@ object EspressoMinimizer extends Minimizer with LazyLogging {
def readTable(espressoTable: String) = {
def bitPat(espresso: String): BitPat = BitPat("b" + espresso.replace('-', '?'))
- espressoTable
+ val out = espressoTable
.split("\n")
.filterNot(_.startsWith("."))
.map(_.split(' '))
.map(row => bitPat(row(0)) -> bitPat(row(1)))
+ // special case for 0 and DontCare, if output is not couple to input
+ if (out.isEmpty)
+ Array(
+ (
+ BitPat(s"b${"?" * table.inputWidth}"),
+ BitPat(s"b${"0" * table.outputWidth}")
+ )
+ )
+ else out
}
val input = writeTable(table)
diff --git a/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala b/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala
index a3481869..26a072f1 100644
--- a/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala
+++ b/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala
@@ -304,24 +304,37 @@ object QMCMinimizer extends Minimizer {
)
})
- minimized.tail.foldLeft(table.copy(table = Seq(minimized.head))) {
- case (tb, t) =>
- if (tb.table.exists(x => x._1 == t._1)) {
- tb.copy(table = tb.table.map {
- case (k, v) =>
- if (k == t._1) {
- def ones(bitPat: BitPat) = bitPat.rawString.zipWithIndex.collect { case ('1', x) => x }
- (
- k,
- BitPat(
- "b" + (0 until v.getWidth).map(i => if ((ones(v) ++ ones(t._2)).contains(i)) "1" else "?").mkString
+ // special case for 0 and DontCare, if output is not couple to input
+ if (minimized.isEmpty)
+ table.copy(
+ Seq(
+ (
+ BitPat(s"b${"?" * table.inputWidth}"),
+ BitPat(s"b${"0" * table.outputWidth}")
+ )
+ )
+ )
+ else
+ minimized.tail.foldLeft(table.copy(table = Seq(minimized.head))) {
+ case (tb, t) =>
+ if (tb.table.exists(x => x._1 == t._1)) {
+ tb.copy(table = tb.table.map {
+ case (k, v) =>
+ if (k == t._1) {
+ def ones(bitPat: BitPat) = bitPat.rawString.zipWithIndex.collect { case ('1', x) => x }
+ (
+ k,
+ BitPat(
+ "b" + (0 until v.getWidth)
+ .map(i => if ((ones(v) ++ ones(t._2)).contains(i)) "1" else "?")
+ .mkString
+ )
)
- )
- } else (k, v)
- })
- } else {
- tb.copy(table = tb.table :+ t)
- }
- }
+ } else (k, v)
+ })
+ } else {
+ tb.copy(table = tb.table :+ t)
+ }
+ }
}
}