summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/chisel3')
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala3
-rw-r--r--src/main/scala/chisel3/stage/ChiselAnnotations.scala16
-rw-r--r--src/main/scala/chisel3/stage/ChiselCli.scala1
-rw-r--r--src/main/scala/chisel3/stage/ChiselOptions.scala23
-rw-r--r--src/main/scala/chisel3/stage/package.scala11
-rw-r--r--src/main/scala/chisel3/stage/phases/Elaborate.scala4
-rw-r--r--src/main/scala/chisel3/util/Arbiter.scala3
-rw-r--r--src/main/scala/chisel3/util/BitPat.scala35
-rw-r--r--src/main/scala/chisel3/util/Bitwise.scala15
-rw-r--r--src/main/scala/chisel3/util/Cat.scala6
-rw-r--r--src/main/scala/chisel3/util/CircuitMath.scala2
-rw-r--r--src/main/scala/chisel3/util/Counter.scala7
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala22
-rw-r--r--src/main/scala/chisel3/util/Reg.scala37
-rw-r--r--src/main/scala/chisel3/util/TransitName.scala11
-rw-r--r--src/main/scala/chisel3/util/Valid.scala3
-rw-r--r--src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala2
-rw-r--r--src/main/scala/chisel3/util/experimental/decode/TruthTable.scala117
18 files changed, 237 insertions, 81 deletions
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
index ba873c23..087bdae2 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
@@ -58,7 +58,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 chiselOptions = view[ChiselOptions](annotationsInAspect)
- val dynamicContext = new DynamicContext(annotationsInAspect, chiselOptions.throwOnFirstError)
+ val dynamicContext =
+ new DynamicContext(annotationsInAspect, chiselOptions.throwOnFirstError, chiselOptions.warnReflectiveNaming)
// 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 e046319d..eda05a7d 100644
--- a/src/main/scala/chisel3/stage/ChiselAnnotations.scala
+++ b/src/main/scala/chisel3/stage/ChiselAnnotations.scala
@@ -79,6 +79,22 @@ case object ThrowOnFirstErrorAnnotation
}
+/** Warn when reflective naming changes names of signals */
+case object WarnReflectiveNamingAnnotation
+ extends NoTargetAnnotation
+ with ChiselOption
+ with HasShellOptions
+ with Unserializable {
+
+ val options = Seq(
+ new ShellOption[Unit](
+ longOption = "warn:reflective-naming",
+ toAnnotationSeq = _ => Seq(this),
+ helpText = "Warn when reflective naming changes the name of signals (3.6 migration)"
+ )
+ )
+}
+
/** 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 f38bf50c..8c5eb79a 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,
+ WarnReflectiveNamingAnnotation,
ChiselOutputFileAnnotation,
ChiselGeneratorAnnotation
)
diff --git a/src/main/scala/chisel3/stage/ChiselOptions.scala b/src/main/scala/chisel3/stage/ChiselOptions.scala
index 7e4305fa..a03f3d7b 100644
--- a/src/main/scala/chisel3/stage/ChiselOptions.scala
+++ b/src/main/scala/chisel3/stage/ChiselOptions.scala
@@ -5,24 +5,27 @@ package chisel3.stage
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) {
+ val runFirrtlCompiler: Boolean = true,
+ val printFullStackTrace: Boolean = false,
+ val throwOnFirstError: Boolean = false,
+ val warnReflectiveNaming: 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
+ runFirrtlCompiler: Boolean = runFirrtlCompiler,
+ printFullStackTrace: Boolean = printFullStackTrace,
+ throwOnFirstError: Boolean = throwOnFirstError,
+ warnReflectiveNaming: Boolean = warnReflectiveNaming,
+ outputFile: Option[String] = outputFile,
+ chiselCircuit: Option[Circuit] = chiselCircuit
): ChiselOptions = {
new ChiselOptions(
runFirrtlCompiler = runFirrtlCompiler,
printFullStackTrace = printFullStackTrace,
throwOnFirstError = throwOnFirstError,
+ warnReflectiveNaming = warnReflectiveNaming,
outputFile = outputFile,
chiselCircuit = chiselCircuit
)
diff --git a/src/main/scala/chisel3/stage/package.scala b/src/main/scala/chisel3/stage/package.scala
index b1064c05..10c8c524 100644
--- a/src/main/scala/chisel3/stage/package.scala
+++ b/src/main/scala/chisel3/stage/package.scala
@@ -15,11 +15,12 @@ package object stage {
def view(options: AnnotationSeq): ChiselOptions = options.collect { case a: ChiselOption => a }
.foldLeft(new ChiselOptions()) { (c, x) =>
x match {
- 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))
+ case NoRunFirrtlCompilerAnnotation => c.copy(runFirrtlCompiler = false)
+ case PrintFullStackTraceAnnotation => c.copy(printFullStackTrace = true)
+ case ThrowOnFirstErrorAnnotation => c.copy(throwOnFirstError = true)
+ case WarnReflectiveNamingAnnotation => c.copy(warnReflectiveNaming = 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 55331cb4..ba29e5f2 100644
--- a/src/main/scala/chisel3/stage/phases/Elaborate.scala
+++ b/src/main/scala/chisel3/stage/phases/Elaborate.scala
@@ -29,8 +29,10 @@ class Elaborate extends Phase {
case ChiselGeneratorAnnotation(gen) =>
val chiselOptions = view[ChiselOptions](annotations)
try {
+ val context =
+ new DynamicContext(annotations, chiselOptions.throwOnFirstError, chiselOptions.warnReflectiveNaming)
val (circuit, dut) =
- Builder.build(Module(gen()), new DynamicContext(annotations, chiselOptions.throwOnFirstError))
+ Builder.build(Module(gen()), context)
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
diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala
index 220a12b1..06821a25 100644
--- a/src/main/scala/chisel3/util/Arbiter.scala
+++ b/src/main/scala/chisel3/util/Arbiter.scala
@@ -6,7 +6,6 @@
package chisel3.util
import chisel3._
-import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order
/** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs
* (selects) at most one.
@@ -115,7 +114,6 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T
* consumer.io.in <> arb.io.out
* }}}
*/
-@chiselName
class RRArbiter[T <: Data](val gen: T, val n: Int) extends LockingRRArbiter[T](gen, n, 1)
/** Hardware module that is used to sequence n producers into 1 consumer.
@@ -131,7 +129,6 @@ class RRArbiter[T <: Data](val gen: T, val n: Int) extends LockingRRArbiter[T](g
* consumer.io.in <> arb.io.out
* }}}
*/
-@chiselName
class Arbiter[T <: Data](val gen: T, val n: Int) extends Module {
val io = IO(new ArbiterIO(gen, n))
diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala
index d27fee14..7cb80e54 100644
--- a/src/main/scala/chisel3/util/BitPat.scala
+++ b/src/main/scala/chisel3/util/BitPat.scala
@@ -5,6 +5,8 @@ package chisel3.util
import scala.language.experimental.macros
import chisel3._
import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform}
+import scala.collection.mutable
+import scala.util.hashing.MurmurHash3
object BitPat {
@@ -253,6 +255,9 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int)
def =/=(that: UInt): Bool = macro SourceInfoTransform.thatArg
def ##(that: BitPat): BitPat = macro SourceInfoTransform.thatArg
+ override def hashCode: Int =
+ MurmurHash3.seqHash(Seq(this.value, this.mask, this.width))
+
/** @group SourceInfoTransformMacro */
def do_apply(x: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): BitPat = {
do_apply(x, x)
@@ -348,15 +353,29 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int)
override def isEmpty: Boolean = false
/** Generate raw string of a [[BitPat]]. */
- def rawString: String = Seq
- .tabulate(width) { i =>
- (value.testBit(width - i - 1), mask.testBit(width - i - 1)) match {
- case (true, true) => "1"
- case (false, true) => "0"
- case (_, false) => "?"
- }
+ def rawString: String = _rawString
+
+ // This is micro-optimized and memoized because it is used for lots of BitPat operations
+ private lazy val _rawString: String = {
+ val sb = new StringBuilder(width)
+ var i = 0
+ while (i < width) {
+ val bitIdx = width - i - 1
+ val char =
+ if (mask.testBit(bitIdx)) {
+ if (value.testBit(bitIdx)) {
+ '1'
+ } else {
+ '0'
+ }
+ } else {
+ '?'
+ }
+ sb += char
+ i += 1
}
- .mkString
+ sb.result()
+ }
override def toString = s"BitPat($rawString)"
}
diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala
index 8abe3645..92ebddb4 100644
--- a/src/main/scala/chisel3/util/Bitwise.scala
+++ b/src/main/scala/chisel3/util/Bitwise.scala
@@ -24,13 +24,16 @@ object FillInterleaved {
*
* Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times)
*/
- def apply(n: Int, in: UInt): UInt = apply(n, in.asBools)
+ def apply(@deprecatedName('n, "Chisel 3.5") n: Int, @deprecatedName('in, "Chisel 3.5") in: UInt): UInt =
+ apply(n, in.asBools)
/** Creates n repetitions of each bit of x in order.
*
* Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times)
*/
- def apply(n: Int, in: Seq[Bool]): UInt = Cat(in.map(Fill(n, _)).reverse)
+ def apply(@deprecatedName('n, "Chisel 3.5") n: Int, @deprecatedName('in, "Chisel 3.5") in: Seq[Bool]): UInt = Cat(
+ in.map(Fill(n, _)).reverse
+ )
}
/** Returns the number of bits set (value is 1 or true) in the input signal.
@@ -45,9 +48,9 @@ object FillInterleaved {
* }}}
*/
object PopCount {
- def apply(in: Iterable[Bool]): UInt = SeqUtils.count(in.toSeq)
+ def apply(@deprecatedName('in, "Chisel 3.5") in: Iterable[Bool]): UInt = SeqUtils.count(in.toSeq)
- def apply(in: Bits): UInt = apply((0 until in.getWidth).map(in(_)))
+ def apply(@deprecatedName('in, "Chisel 3.5") in: Bits): UInt = apply((0 until in.getWidth).map(in(_)))
}
/** Create repetitions of the input using a tree fanout topology.
@@ -65,7 +68,7 @@ object Fill {
* Output data-equivalent to x ## x ## ... ## x (n repetitions).
* @throws java.lang.IllegalArgumentException if `n` is less than zero
*/
- def apply(n: Int, x: UInt): UInt = {
+ def apply(@deprecatedName('n, "Chisel 3.5") n: Int, @deprecatedName('x, "Chisel 3.5") x: UInt): UInt = {
n match {
case _ if n < 0 => throw new IllegalArgumentException(s"n (=$n) must be nonnegative integer.")
case 0 => UInt(0.W)
@@ -111,5 +114,5 @@ object Reverse {
Cat(doit(in(half - 1, 0), half), doit(in(length - 1, half), length - half))
}
- def apply(in: UInt): UInt = doit(in, in.getWidth)
+ def apply(@deprecatedName('in, "Chisel 3.5") in: UInt): UInt = doit(in, in.getWidth)
}
diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala
index c5adce56..3224ec03 100644
--- a/src/main/scala/chisel3/util/Cat.scala
+++ b/src/main/scala/chisel3/util/Cat.scala
@@ -19,7 +19,9 @@ object Cat {
/** Concatenates the argument data elements, in argument order, together. The first argument
* forms the most significant bits, while the last argument forms the least significant bits.
*/
- def apply[T <: Bits](a: T, r: T*): UInt = apply(a :: r.toList)
+ def apply[T <: Bits](@deprecatedName('a, "Chisel 3.5") a: T, @deprecatedName('r, "Chisel 3.5") r: T*): UInt = apply(
+ a :: r.toList
+ )
/** Concatenates the data elements of the input sequence, in reverse sequence order, together.
* The first element of the sequence forms the most significant bits, while the last element
@@ -28,5 +30,5 @@ object Cat {
* Equivalent to r(0) ## r(1) ## ... ## r(n-1).
* @note This returns a `0.U` if applied to a zero-element `Vec`.
*/
- def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse)
+ def apply[T <: Bits](@deprecatedName('r, "Chisel 3.5") r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse)
}
diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala
index df60f059..9e4890a9 100644
--- a/src/main/scala/chisel3/util/CircuitMath.scala
+++ b/src/main/scala/chisel3/util/CircuitMath.scala
@@ -6,7 +6,6 @@
package chisel3.util
import chisel3._
-import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order
/** Returns the base-2 integer logarithm of an UInt.
*
@@ -22,7 +21,6 @@ object Log2 {
/** Returns the base-2 integer logarithm of the least-significant `width` bits of an UInt.
*/
- @chiselName
def apply(x: Bits, width: Int): UInt = {
if (width < 2) {
0.U
diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala
index ef1eff9f..be6e3257 100644
--- a/src/main/scala/chisel3/util/Counter.scala
+++ b/src/main/scala/chisel3/util/Counter.scala
@@ -3,7 +3,7 @@
package chisel3.util
import chisel3._
-import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order
+import chisel3.experimental.AffectsChiselPrefix
/** Used to generate an inline (logic directly in the containing Module, no internal Module is created)
* hardware counter.
@@ -27,8 +27,7 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because
* }
* }}}
*/
-@chiselName
-class Counter private (r: Range, oldN: Option[Int] = None) {
+class Counter private (r: Range, oldN: Option[Int] = None) extends AffectsChiselPrefix {
require(r.length > 0, s"Counter range cannot be empty, got: $r")
require(r.start >= 0 && r.end >= 0, s"Counter range must be positive, got: $r")
@@ -113,7 +112,6 @@ object Counter {
* @return tuple of the counter value and whether the counter will wrap (the value is at
* maximum and the condition is true).
*/
- @chiselName
def apply(cond: Bool, n: Int): (UInt, Bool) = {
val c = new Counter(n)
val wrap = WireInit(false.B)
@@ -129,7 +127,6 @@ object Counter {
* @return tuple of the counter value and whether the counter will wrap (the value is at
* maximum and the condition is true).
*/
- @chiselName
def apply(r: Range, enable: Bool = true.B, reset: Bool = false.B): (UInt, Bool) = {
val c = new Counter(r)
val wrap = WireInit(false.B)
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index 5c71a4ea..b21bd04f 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -9,6 +9,8 @@ import chisel3._
import chisel3.experimental.{requireIsChiselType, DataMirror, Direction}
import chisel3.internal.naming._ // can't use chisel3_ version because of compile order
+import scala.annotation.nowarn
+
/** An I/O Bundle containing 'valid' and 'ready' signals that handshake
* the transfer of data stored in the 'bits' subfield.
* The base protocol implied by the directionality is that
@@ -97,7 +99,22 @@ object ReadyValidIO {
* of ready or valid.
* @param gen the type of data to be wrapped in DecoupledIO
*/
-class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen)
+class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) {
+
+ /** Applies the supplied functor to the bits of this interface, returning a new
+ * typed DecoupledIO interface.
+ * @param f The function to apply to this DecoupledIO's 'bits' with return type B
+ * @return a new DecoupledIO of type B
+ */
+ def map[B <: Data](f: T => B): DecoupledIO[B] = {
+ val _map_bits = f(bits)
+ val _map = Wire(Decoupled(chiselTypeOf(_map_bits)))
+ _map.bits := _map_bits
+ _map.valid := valid
+ ready := _map.ready
+ _map
+ }
+}
/** This factory adds a decoupled handshaking protocol to a data bundle. */
object Decoupled {
@@ -231,7 +248,6 @@ class QueueIO[T <: Data](
* consumer.io.in <> q.io.deq
* }}}
*/
-@chiselName
class Queue[T <: Data](
val gen: T,
val entries: Int,
@@ -342,7 +358,7 @@ object Queue {
* consumer.io.in <> Queue(producer.io.out, 16)
* }}}
*/
- @chiselName
+ @nowarn("cat=deprecation&msg=TransitName")
def apply[T <: Data](
enq: ReadyValidIO[T],
entries: Int = 2,
diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala
index ddb74dd6..89381c11 100644
--- a/src/main/scala/chisel3/util/Reg.scala
+++ b/src/main/scala/chisel3/util/Reg.scala
@@ -12,7 +12,10 @@ object RegEnable {
* val regWithEnable = RegEnable(nextVal, ena)
* }}}
*/
- def apply[T <: Data](next: T, enable: Bool): T = {
+ def apply[T <: Data](
+ @deprecatedName('next, "Chisel 3.5") next: T,
+ @deprecatedName('enable, "Chisel 3.5") enable: Bool
+ ): T = {
val r = Reg(chiselTypeOf(next))
when(enable) { r := next }
r
@@ -24,7 +27,11 @@ object RegEnable {
* val regWithEnableAndReset = RegEnable(nextVal, 0.U, ena)
* }}}
*/
- def apply[T <: Data](next: T, init: T, enable: Bool): T = {
+ def apply[T <: Data](
+ @deprecatedName('next, "Chisel 3.5") next: T,
+ @deprecatedName('init, "Chisel 3.5") init: T,
+ @deprecatedName('enable, "Chisel 3.5") enable: Bool
+ ): T = {
val r = RegInit(init)
when(enable) { r := next }
r
@@ -43,7 +50,11 @@ object ShiftRegister {
* val regDelayTwo = ShiftRegister(nextVal, 2, ena)
* }}}
*/
- def apply[T <: Data](in: T, n: Int, en: Bool = true.B): T = ShiftRegisters(in, n, en).lastOption.getOrElse(in)
+ def apply[T <: Data](
+ @deprecatedName('in, "Chisel 3.5") in: T,
+ @deprecatedName('n, "Chisel 3.5") n: Int,
+ @deprecatedName('en, "Chisel 3.5") en: Bool = true.B
+ ): T = ShiftRegisters(in, n, en).lastOption.getOrElse(in)
/** Returns the n-cycle delayed version of the input signal with reset initialization.
*
@@ -56,7 +67,12 @@ object ShiftRegister {
* val regDelayTwoReset = ShiftRegister(nextVal, 2, 0.U, ena)
* }}}
*/
- def apply[T <: Data](in: T, n: Int, resetData: T, en: Bool): T =
+ def apply[T <: Data](
+ @deprecatedName('in, "Chisel 3.5") in: T,
+ @deprecatedName('n, "Chisel 3.5") n: Int,
+ @deprecatedName('resetData, "Chisel 3.5") resetData: T,
+ @deprecatedName('en, "Chisel 3.5") en: Bool
+ ): T =
ShiftRegisters(in, n, resetData, en).lastOption.getOrElse(in)
}
@@ -68,7 +84,11 @@ object ShiftRegisters {
* @param n number of cycles to delay
* @param en enable the shift
*/
- def apply[T <: Data](in: T, n: Int, en: Bool = true.B): Seq[T] =
+ def apply[T <: Data](
+ @deprecatedName('in, "Chisel 3.5") in: T,
+ @deprecatedName('n, "Chisel 3.5") n: Int,
+ @deprecatedName('en, "Chisel 3.5") en: Bool = true.B
+ ): Seq[T] =
Seq.iterate(in, n + 1)(util.RegEnable(_, en)).drop(1)
/** Returns delayed input signal registers with reset initialization from 1 to n.
@@ -78,6 +98,11 @@ object ShiftRegisters {
* @param resetData reset value for each register in the shift
* @param en enable the shift
*/
- def apply[T <: Data](in: T, n: Int, resetData: T, en: Bool): Seq[T] =
+ def apply[T <: Data](
+ @deprecatedName('in, "Chisel 3.5") in: T,
+ @deprecatedName('n, "Chisel 3.5") n: Int,
+ @deprecatedName('resetData, "Chisel 3.5") resetData: T,
+ @deprecatedName('en, "Chisel 3.5") en: Bool
+ ): Seq[T] =
Seq.iterate(in, n + 1)(util.RegEnable(_, resetData, en)).drop(1)
}
diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala
index cc8f2456..8b509db5 100644
--- a/src/main/scala/chisel3/util/TransitName.scala
+++ b/src/main/scala/chisel3/util/TransitName.scala
@@ -42,6 +42,12 @@ object TransitName {
* @param to the thing that will receive the "good" name
* @return the `from` parameter
*/
+ @deprecated(
+ "Use suggestName or rely on the naming plugin instead of this function: \n" +
+ " val from = {to}\n" +
+ " val from = prefix(prefixYouWant){to}",
+ "Chisel 3.5.4"
+ )
def apply[T <: HasId](from: T, to: HasId): T = {
// To transit a name, we need to hook on both the suggestName and autoSeed mechanisms
from.addSuggestPostnameHook((given_name: String) => { to.suggestName(given_name) })
@@ -55,6 +61,11 @@ object TransitName {
* @param to the thing that will receive the "good" name
* @return the `from` parameter
*/
+ @deprecated(
+ "Use suggestName or rely on the naming plugin instead of this function. Use prefix instead of suffix: \n" +
+ " val from = prefix(prefixYouWant){to}",
+ "Chisel 3.5.4"
+ )
def withSuffix[T <: HasId](suffix: String)(from: T, to: HasId): T = {
// To transit a name, we need to hook on both the suggestName and autoSeed mechanisms
from.addSuggestPostnameHook((given_name: String) => { to.suggestName(given_name + suffix) })
diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala
index eeb2ab68..cb0e166a 100644
--- a/src/main/scala/chisel3/util/Valid.scala
+++ b/src/main/scala/chisel3/util/Valid.scala
@@ -7,6 +7,8 @@ package chisel3.util
import chisel3._
+import scala.annotation.nowarn
+
/** A [[Bundle]] that adds a `valid` bit to some data. This indicates that the user expects a "valid" interface between
* a producer and a consumer. Here, the producer asserts the `valid` bit when data on the `bits` line contains valid
* data. This differs from [[DecoupledIO]] or [[IrrevocableIO]] as there is no `ready` line that the consumer can use
@@ -116,6 +118,7 @@ object Pipe {
* @param latency the number of pipeline stages
* @return $returnType
*/
+ @nowarn("cat=deprecation&msg=TransitName")
def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int)(implicit compileOptions: CompileOptions): Valid[T] = {
require(latency >= 0, "Pipe latency must be greater than or equal to zero!")
if (latency == 0) {
diff --git a/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala b/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala
index 86973e5b..8c85b6d1 100644
--- a/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala
+++ b/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala
@@ -87,6 +87,6 @@ object EspressoMinimizer extends Minimizer with LazyLogging {
logger.trace(s"""espresso output table:
|$output
|""".stripMargin)
- TruthTable(readTable(output), table.default)
+ TruthTable.fromEspressoOutput(readTable(output), table.default)
}
}
diff --git a/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala b/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala
index 00fa0f9c..2720e690 100644
--- a/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala
+++ b/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala
@@ -3,6 +3,7 @@
package chisel3.util.experimental.decode
import chisel3.util.BitPat
+import scala.collection.mutable
sealed class TruthTable private (val table: Seq[(BitPat, BitPat)], val default: BitPat, val sort: Boolean) {
def inputWidth = table.head._1.getWidth
@@ -29,40 +30,89 @@ sealed class TruthTable private (val table: Seq[(BitPat, BitPat)], val default:
object TruthTable {
- /** Convert a table and default output into a [[TruthTable]]. */
- def apply(table: Iterable[(BitPat, BitPat)], default: BitPat, sort: Boolean = true): TruthTable = {
+ /** Pad the input signals to equalize all input widths. Pads input signals
+ * to the maximum width found in the table.
+ *
+ * @param table the truth table whose rows will be padded
+ * @return the same truth table but with inputs padded
+ */
+ private def padInputs(table: Iterable[(BitPat, BitPat)]): Iterable[(BitPat, BitPat)] = {
val inputWidth = table.map(_._1.getWidth).max
- require(table.map(_._2.getWidth).toSet.size == 1, "output width not equal.")
- val outputWidth = table.map(_._2.getWidth).head
- val mergedTable = table.map {
- // pad input signals if necessary
+ table.map {
case (in, out) if inputWidth > in.width =>
(BitPat.N(inputWidth - in.width) ## in, out)
case (in, out) => (in, out)
}
- .groupBy(_._1.toString)
- .map {
- case (key, values) =>
- // merge same input inputs.
- values.head._1 -> BitPat(s"b${Seq
- .tabulate(outputWidth) { i =>
- val outputSet = values
- .map(_._2)
- .map(_.rawString)
- .map(_(i))
- .toSet
- .filterNot(_ == '?')
- require(
- outputSet.size != 2,
- s"TruthTable conflict in :\n${values.map { case (i, o) => s"${i.rawString}->${o.rawString}" }.mkString("\n")}"
- )
- outputSet.headOption.getOrElse('?')
- }
- .mkString}")
- }
- .toSeq
+ }
+
+ /** For each duplicated input, collect the outputs into a single Seq.
+ *
+ * @param table the truth table
+ * @return a Seq of tuple of length 2, where the first element is the
+ * input and the second element is a Seq of OR-ed outputs
+ * for the input
+ */
+ private def mergeTableOnInputs(table: Iterable[(BitPat, BitPat)]): Seq[(BitPat, Seq[BitPat])] = {
+ groupByIntoSeq(table)(_._1).map {
+ case (input, mappings) =>
+ input -> mappings.map(_._2)
+ }
+ }
+
+ /** Merge two BitPats by OR-ing the values and masks, and setting the
+ * width to the max width among the two
+ */
+ private def merge(a: BitPat, b: BitPat): BitPat = {
+ new BitPat(a.value | b.value, a.mask | b.mask, a.width.max(b.width))
+ }
+
+ /** Public method for calling with the Espresso decoder format fd
+ *
+ * For Espresso, for each output, a 1 means this product term belongs to the ON-set,
+ * a 0 means this product term has no meaning for the value of this function.
+ * This is the same as the fd (or f) type in espresso.
+ *
+ * @param table the truth table
+ * @param default the default BitPat is made up of a single bit type, either "?", "0" or "1".
+ * A default of "?" sets Espresso to fr-format, while a "0" or "1" sets it to the
+ * fd-format.
+ * @param sort whether to sort the final truth table using BitPat.bitPatOrder
+ * @return a fully built TruthTable
+ */
+ def fromEspressoOutput(table: Iterable[(BitPat, BitPat)], default: BitPat, sort: Boolean = true): TruthTable = {
+ apply_impl(table, default, sort, false)
+ }
+
+ /** Public apply method to TruthTable. Calls apply_impl with the default value true of checkCollisions */
+ def apply(table: Iterable[(BitPat, BitPat)], default: BitPat, sort: Boolean = true): TruthTable = {
+ apply_impl(table, default, sort, true)
+ }
+
+ /** Convert a table and default output into a [[TruthTable]]. */
+ private def apply_impl(
+ table: Iterable[(BitPat, BitPat)],
+ default: BitPat,
+ sort: Boolean,
+ checkCollisions: Boolean
+ ): TruthTable = {
+ val paddedTable = padInputs(table)
+
+ require(table.map(_._2.getWidth).toSet.size == 1, "output width not equal.")
+
+ val mergedTable = mergeTableOnInputs(paddedTable)
+
+ val finalTable: Seq[(BitPat, BitPat)] = mergedTable.map {
+ case (input, outputs) =>
+ val (result, noCollisions) = outputs.tail.foldLeft((outputs.head, checkCollisions)) {
+ case ((acc, ok), o) => (merge(acc, o), ok && acc.overlap(o))
+ }
+ // Throw an error if checkCollisions is true but there are bits with a non-zero overlap.
+ require(!checkCollisions || noCollisions, s"TruthTable conflict on merged row:\n $input -> $outputs")
+ (input, result)
+ }
+
import BitPat.bitPatOrder
- new TruthTable(if (sort) mergedTable.sorted else mergedTable, default, sort)
+ new TruthTable(if (sort) finalTable.sorted else finalTable, default, sort)
}
/** Parse TruthTable from its string representation. */
@@ -140,4 +190,15 @@ object TruthTable {
bitPat(tables.flatMap { case (table, indexes) => table.default.rawString.zip(indexes) })
)
}
+
+ /** Similar to Seq.groupBy except that it preserves ordering of elements within each group */
+ private def groupByIntoSeq[A, K](xs: Iterable[A])(f: A => K): Seq[(K, Seq[A])] = {
+ val map = mutable.LinkedHashMap.empty[K, mutable.ListBuffer[A]]
+ for (x <- xs) {
+ val key = f(x)
+ val l = map.getOrElseUpdate(key, mutable.ListBuffer.empty[A])
+ l += x
+ }
+ map.view.map({ case (k, vs) => k -> vs.toList }).toList
+ }
}