summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3
diff options
context:
space:
mode:
authorJiuyang Liu2021-05-06 16:20:50 +0000
committerJiuyang Liu2021-06-16 10:32:04 +0800
commit3691fe61cc43beb0e7d0f813723d4150daa79372 (patch)
treeda0335facf1d4c6abfe4faff919b6159021463f7 /src/main/scala/chisel3
parent819e806664da117172b6d46aa1adf83d39042d48 (diff)
add a simple decoder API.
Diffstat (limited to 'src/main/scala/chisel3')
-rw-r--r--src/main/scala/chisel3/util/experimental/decode/DecodeTableAnnotation.scala4
-rw-r--r--src/main/scala/chisel3/util/experimental/decode/decoder.scala53
2 files changed, 55 insertions, 2 deletions
diff --git a/src/main/scala/chisel3/util/experimental/decode/DecodeTableAnnotation.scala b/src/main/scala/chisel3/util/experimental/decode/DecodeTableAnnotation.scala
index 3a6957e2..cd289a5d 100644
--- a/src/main/scala/chisel3/util/experimental/decode/DecodeTableAnnotation.scala
+++ b/src/main/scala/chisel3/util/experimental/decode/DecodeTableAnnotation.scala
@@ -6,8 +6,8 @@ import firrtl.annotations.{Annotation, ReferenceTarget, SingleTargetAnnotation}
case class DecodeTableAnnotation(
target: ReferenceTarget,
- truthTable: TruthTable,
- minimizedTable: TruthTable)
+ truthTable: String,
+ minimizedTable: String)
extends SingleTargetAnnotation[ReferenceTarget] {
override def duplicate(n: ReferenceTarget): Annotation = this.copy(target = n)
}
diff --git a/src/main/scala/chisel3/util/experimental/decode/decoder.scala b/src/main/scala/chisel3/util/experimental/decode/decoder.scala
new file mode 100644
index 00000000..2ef474e1
--- /dev/null
+++ b/src/main/scala/chisel3/util/experimental/decode/decoder.scala
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.util.experimental.decode
+
+import chisel3._
+import chisel3.experimental.{ChiselAnnotation, annotate}
+import chisel3.util.{BitPat, pla}
+import chisel3.util.experimental.getAnnotations
+import firrtl.annotations.Annotation
+import logger.LazyLogging
+
+object decoder extends LazyLogging {
+ def apply(minimizer: Minimizer, input: UInt, truthTable: TruthTable): UInt = {
+ val minimizedTable = getAnnotations().collect {
+ case DecodeTableAnnotation(_, in, out) => TruthTable(in) -> TruthTable(out)
+ }.toMap.getOrElse(
+ {
+ logger.trace(s"""Decoder Cache Hit!
+ |${truthTable.table}
+ |""".stripMargin)
+ truthTable
+ }, {
+ val startTime = System.nanoTime()
+ val minimizedTable = minimizer.minimize(truthTable)
+ val totalTime = System.nanoTime() - startTime
+ val totalTimeInSeconds = totalTime / 1e9
+ val info = f"Logic Minimize with $minimizer finished in ${totalTimeInSeconds} second"
+ if (totalTimeInSeconds > 5)
+ logger.error(
+ s"$info spends too long, consider using chisel3.util.experimental.DecodeTableAnnotation to cache decode result or switch to EspressoMinimizer."
+ )
+ else logger.trace(info)
+ minimizedTable
+ }
+ )
+ if (minimizedTable.table.isEmpty) {
+ val outputs = Wire(UInt(minimizedTable.default.getWidth.W))
+ outputs := minimizedTable.default.value.U(minimizedTable.default.getWidth.W)
+ outputs
+ } else {
+ val (plaInput, plaOutput) =
+ pla(minimizedTable.table.toSeq, BitPat(minimizedTable.default.value.U(minimizedTable.default.getWidth.W)))
+
+ annotate(new ChiselAnnotation {
+ override def toFirrtl: Annotation =
+ DecodeTableAnnotation(plaOutput.toTarget, truthTable.toString, minimizedTable.toString)
+ })
+
+ plaInput := input
+ plaOutput
+ }
+ }
+}