Skip to content

Commit

Permalink
Optimize BitPat factory from UInt literals (#3988)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkoenig committed Apr 11, 2024
1 parent 1ecab68 commit 121b265
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/main/scala/chisel3/util/BitPat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ object BitPat {
*/
def apply(x: UInt): BitPat = {
require(x.isLit, s"$x is not a literal, BitPat.apply(x: UInt) only accepts literals")
val len = if (x.isWidthKnown) x.getWidth else 0
apply("b" + x.litValue.toString(2).reverse.padTo(len, "0").reverse.mkString)
val width = x.getWidth.max(1) // BitPat doesn't support zero-width
val mask = (BigInt(1) << width) - 1
new BitPat(x.litValue, mask, width)
}

implicit class fromUIntToBitPatComparable(x: UInt) extends SourceInfoDoc {
Expand Down
10 changes: 10 additions & 0 deletions src/test/scala/chiselTests/util/BitPatSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package chiselTests.util

import chisel3._
import chisel3.util.BitPat
import _root_.circt.stage.ChiselStage
import org.scalatest.flatspec.AnyFlatSpec
Expand Down Expand Up @@ -49,4 +50,13 @@ class BitPatSpec extends AnyFlatSpec with Matchers {
b(4, 3) should be(BitPat("b01"))
b(6, 6) should be(BitPat("b1"))
}

it should "parse UInt literals correctly" in {
BitPat(0.U) should be(new BitPat(0, 1, 1))
// Note that this parses as 1-bit width, there are other APIs that don't support zero-width UInts correctly
BitPat(0.U(0.W)) should be(new BitPat(0, 1, 1))
BitPat(1.U) should be(new BitPat(1, 1, 1))
BitPat(2.U) should be(new BitPat(2, 3, 2))
BitPat(0xdeadbeefL.U) should be(new BitPat(BigInt("deadbeef", 16), BigInt("ffffffff", 16), 32))
}
}

0 comments on commit 121b265

Please sign in to comment.