From 99ae2eeb9decb3bc3a789053889f608bb1a103b9 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 13 May 2022 19:45:59 -0700 Subject: Deprecate named arguments for methods moving to macros in 3.6 (#2530) These methods will start using def macros and since def macros do not supported named arguments this will be a source-incompatible change. This deprecation will warn users that they need to remove any uses of named arguments on these methods.--- src/main/scala/chisel3/util/Bitwise.scala | 15 ++++++++----- src/main/scala/chisel3/util/Cat.scala | 6 +++-- src/main/scala/chisel3/util/Reg.scala | 37 ++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 14 deletions(-) (limited to 'src/main/scala/chisel3/util') 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/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) } -- cgit v1.2.3 From 4b8981d627fc307161ff39b78836e37212803756 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Sat, 11 Jun 2022 00:13:36 +0000 Subject: Micro-optimize BitPat.rawString (#2577) (#2578) BitPat.rawString is called a lot when decoding and is used for certain BitPat operations. We should use it less but this is at least a bandaid. (cherry picked from commit c11af20fe5b211ec72ba00f3ce0880d7933e566b) Co-authored-by: Jack Koenig --- src/main/scala/chisel3/util/BitPat.scala | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index d27fee14..33dd5b2b 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -348,15 +348,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)" } -- cgit v1.2.3 From 3063a1b853726e0bc65d7211ea2e584275774412 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Mon, 27 Jun 2022 16:38:41 +0000 Subject: Deprecate TransitName (backport #2603) (#2606) * Deprecate TransitName (#2603) * Deprecate TransitName * Add @nowarn macros to usages of TransitName in the repo Co-authored-by: Jack Koenig (cherry picked from commit a0b05190e5303ec28a0c7abe645d81e9a72023ff) * Update src/main/scala/chisel3/util/Valid.scala * Update src/main/scala/chisel3/util/Valid.scala Co-authored-by: Megan Wachs --- src/main/scala/chisel3/util/Decoupled.scala | 3 +++ src/main/scala/chisel3/util/TransitName.scala | 11 +++++++++++ src/main/scala/chisel3/util/Valid.scala | 3 +++ 3 files changed, 17 insertions(+) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 5c71a4ea..42717b66 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 @@ -342,6 +344,7 @@ object Queue { * consumer.io.in <> Queue(producer.io.out, 16) * }}} */ + @nowarn("cat=deprecation&msg=TransitName") @chiselName def apply[T <: Data]( enq: ReadyValidIO[T], 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) { -- cgit v1.2.3 From 2b977a74293a49e9e2a5d960a6a9c07df22430ce Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Wed, 6 Jul 2022 00:28:02 +0000 Subject: Implement trait for Chisel compiler to name arbitrary non-Data types (#2610) (#2617) Co-authored-by: Jack Koenig Co-authored-by: Megan Wachs (cherry picked from commit 3ab34cddd8b87c22d5fc31020f10ddb2f1990d51) Co-authored-by: Jared Barocsi <82000041+jared-barocsi@users.noreply.github.com>--- src/main/scala/chisel3/util/Counter.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index ef1eff9f..0d1b8db1 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -3,6 +3,7 @@ package chisel3.util import chisel3._ +import chisel3.experimental.AffectsChiselPrefix import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order /** Used to generate an inline (logic directly in the containing Module, no internal Module is created) @@ -27,8 +28,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") -- cgit v1.2.3 From 4f10bdd703d7559cddae50541cf7c8e0a1c1d4c0 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Wed, 6 Jul 2022 21:42:13 +0000 Subject: Refactor TruthTable.apply and add factory method for Espresso (backport #2612) (#2620) * Refactor TruthTable.apply and add factory method for Espresso (#2612) Improves performance of creating TruthTables by processing entire BitPats rather than individual bits. New TruthTable factory method enables constructing TruthTables with semantics of OR-ing output BitPats together rather than erroring when multiple terms have the same input BitPat. This alternative factory method matches semantics for the output format of Espresso. Co-authored-by: Megan Wachs Co-authored-by: Jack Koenig (cherry picked from commit 231f14e74f112a9f721e774561126b2bd1250039) # Conflicts: # src/main/scala/chisel3/util/BitPat.scala * Resolve backport conflicts Co-authored-by: Aditya Naik <91489422+adkian-sifive@users.noreply.github.com>--- src/main/scala/chisel3/util/BitPat.scala | 5 + .../experimental/decode/EspressoMinimizer.scala | 2 +- .../util/experimental/decode/TruthTable.scala | 117 ++++++++++++++++----- 3 files changed, 95 insertions(+), 29 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 33dd5b2b..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) 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 + } } -- cgit v1.2.3 From f46d02f55bd22ffda32b20e8cc4b40aa96b03ee0 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Thu, 21 Jul 2022 14:16:11 -0700 Subject: Deprecate chiselName and NoChiselNamePrefix trait (#2627) (#2633) Also remove all non-testing uses of chiselName. (cherry picked from commit 1c5d1b5317a0c9fe7ef9d15138065a817380a1e4) Co-authored-by: Jared Barocsi <82000041+jared-barocsi@users.noreply.github.com>--- src/main/scala/chisel3/util/Arbiter.scala | 3 --- src/main/scala/chisel3/util/CircuitMath.scala | 2 -- src/main/scala/chisel3/util/Counter.scala | 3 --- src/main/scala/chisel3/util/Decoupled.scala | 2 -- 4 files changed, 10 deletions(-) (limited to 'src/main/scala/chisel3/util') 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/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 0d1b8db1..be6e3257 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -4,7 +4,6 @@ package chisel3.util import chisel3._ import chisel3.experimental.AffectsChiselPrefix -import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order /** Used to generate an inline (logic directly in the containing Module, no internal Module is created) * hardware counter. @@ -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 42717b66..f02a4116 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -233,7 +233,6 @@ class QueueIO[T <: Data]( * consumer.io.in <> q.io.deq * }}} */ -@chiselName class Queue[T <: Data]( val gen: T, val entries: Int, @@ -345,7 +344,6 @@ object Queue { * }}} */ @nowarn("cat=deprecation&msg=TransitName") - @chiselName def apply[T <: Data]( enq: ReadyValidIO[T], entries: Int = 2, -- cgit v1.2.3 From e52739f2fe587cedd657a331b7d7ba0c75b919c6 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Thu, 28 Jul 2022 22:27:29 +0000 Subject: Implement DecoupledIO.map utility (#2646) (#2649) (cherry picked from commit b20df1d6cda03f6eef28ee480e0aade914c5face) Co-authored-by: Jared Barocsi <82000041+jared-barocsi@users.noreply.github.com>--- src/main/scala/chisel3/util/Decoupled.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index f02a4116..b21bd04f 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -99,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 { -- cgit v1.2.3