summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/util/BitPat.scala
diff options
context:
space:
mode:
authorJiuyang Liu2021-08-27 04:37:34 +0800
committerGitHub2021-08-26 20:37:34 +0000
commite74b978d5188d9cd28e3520912d858d228136e75 (patch)
tree1b391cb548b37b604c9aeb9dad39817deb805837 /src/main/scala/chisel3/util/BitPat.scala
parent3840fec3d918f23df07a18311136ac6a1bc365e1 (diff)
add new APIs to BitPat (#2076)
* add Y and N to BitPat. * add ## for BitPat. * add rawString API. * use rawString in decoder * add select and slice to BitPat.
Diffstat (limited to 'src/main/scala/chisel3/util/BitPat.scala')
-rw-r--r--src/main/scala/chisel3/util/BitPat.scala53
1 files changed, 45 insertions, 8 deletions
diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala
index 985d22da..0dcb2466 100644
--- a/src/main/scala/chisel3/util/BitPat.scala
+++ b/src/main/scala/chisel3/util/BitPat.scala
@@ -58,6 +58,22 @@ object BitPat {
*/
def dontCare(width: Int): BitPat = BitPat("b" + ("?" * width))
+ /** Creates a [[BitPat]] of all 1 of the specified bitwidth.
+ *
+ * @example {{{
+ * val myY = BitPat.Y(4) // equivalent to BitPat("b1111")
+ * }}}
+ */
+ def Y(width: Int = 1): BitPat = BitPat("b" + ("1" * width))
+
+ /** Creates a [[BitPat]] of all 0 of the specified bitwidth.
+ *
+ * @example {{{
+ * val myN = BitPat.N(4) // equivalent to BitPat("b0000")
+ * }}}
+ */
+ def N(width: Int = 1): BitPat = BitPat("b" + ("0" * width))
+
/** Allows BitPats to be used where a UInt is expected.
*
* @note the BitPat must not have don't care bits (will error out otherwise)
@@ -106,9 +122,11 @@ object BitPat {
*/
sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) extends SourceInfoDoc {
def getWidth: Int = width
+ def apply(x: Int): BitPat = macro SourceInfoTransform.xArg
+ def apply(x: Int, y: Int): BitPat = macro SourceInfoTransform.xyArg
def === (that: UInt): Bool = macro SourceInfoTransform.thatArg
def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg
-
+ def ## (that: BitPat): BitPat = macro SourceInfoTransform.thatArg
override def equals(obj: Any): Boolean = {
obj match {
case y: BitPat => value == y.value && mask == y.mask && getWidth == y.getWidth
@@ -117,6 +135,18 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) extends Sou
}
/** @group SourceInfoTransformMacro */
+ def do_apply(x: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): BitPat = {
+ do_apply(x, x)
+ }
+
+ /** @group SourceInfoTransformMacro */
+ def do_apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): BitPat = {
+ require(width > x && y >= 0, s"Invalid bit range ($x, $y), index should be bounded by (${width - 1}, 0)")
+ require(x >= y, s"Invalid bit range ($x, $y), x should be greater or equal to y.")
+ BitPat(s"b${rawString.slice(width - x - 1, width - y)}")
+ }
+
+ /** @group SourceInfoTransformMacro */
def do_=== (that: UInt)
(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
value.asUInt === (that & mask.asUInt)
@@ -126,12 +156,19 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) extends Sou
(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
!(this === that)
}
-
- override def toString = {
- "BitPat(" +
- (0 until width).map(i =>
- if (((mask >> i) & 1) == 1) if (((value >> i) & 1) == 1) "1" else "0" else "?"
- ).reverse.reduce(_ + _) +
- ")"
+ /** @group SourceInfoTransformMacro */
+ def do_##(that: BitPat)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): BitPat = {
+ new BitPat((value << that.getWidth) + that.value, (mask << that.getWidth) + that.mask, this.width + that.getWidth)
}
+
+ /** 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) => "?"
+ }
+ }.mkString
+
+ override def toString = s"BitPat($rawString)"
}