diff options
| author | Jiuyang Liu | 2021-08-27 04:37:34 +0800 |
|---|---|---|
| committer | GitHub | 2021-08-26 20:37:34 +0000 |
| commit | e74b978d5188d9cd28e3520912d858d228136e75 (patch) | |
| tree | 1b391cb548b37b604c9aeb9dad39817deb805837 /src/main/scala/chisel3/util/BitPat.scala | |
| parent | 3840fec3d918f23df07a18311136ac6a1bc365e1 (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.scala | 53 |
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)" } |
