1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
// See LICENSE for license details.
package Chisel
object BitPat {
/** Parses a bit pattern string into (bits, mask, width).
*
* @return bits the literal value, with don't cares being 0
* @return mask the mask bits, with don't cares being 0 and cares being 1
* @return width the number of bits in the literal, including values and
* don't cares.
*/
private def parse(x: String): (BigInt, BigInt, Int) = {
// REVIEW TODO: can this be merged with literal parsing creating one unified
// Chisel string to value decoder (which can also be invoked by libraries
// and testbenches?
// REVIEW TODO: Verilog Xs also handle octal and hex cases.
require(x.head == 'b', "BitPats must be in binary and be prefixed with 'b'")
var bits = BigInt(0)
var mask = BigInt(0)
for (d <- x.tail) {
if (d != '_') {
if (!"01?".contains(d)) Builder.error({"Literal: " + x + " contains illegal character: " + d})
mask = (mask << 1) + (if (d == '?') 0 else 1)
bits = (bits << 1) + (if (d == '1') 1 else 0)
}
}
(bits, mask, x.length - 1)
}
/** Creates a [[BitPat]] literal from a string.
*
* @param n the literal value as a string, in binary, prefixed with 'b'
* @note legal characters are '0', '1', and '?', as well as '_' as white
* space (which are ignored)
*/
def apply(n: String): BitPat = {
val (bits, mask, width) = parse(n)
new BitPat(bits, mask, width)
}
/** Creates a [[BitPat]] of all don't cares of a specified width. */
// REVIEW TODO: is this really necessary? if so, can there be a better name?
def DC(width: Int): BitPat = BitPat("b" + ("?" * width))
// BitPat <-> UInt
/** enable conversion of a bit pattern to a UInt */
// REVIEW TODO: Doesn't having a BitPat with all mask bits high defeat the
// point of using a BitPat in the first place?
implicit def BitPatToUInt(x: BitPat): UInt = {
require(x.mask == (BigInt(1) << x.getWidth) - 1)
UInt(x.value, x.getWidth)
}
/** create a bit pattern from a UInt */
// REVIEW TODO: Similar, what is the point of this?
implicit def apply(x: UInt): BitPat = {
require(x.isLit)
BitPat("b" + x.litValue.toString(2))
}
}
// TODO: Break out of Core? (this doesn't involve FIRRTL generation)
/** Bit patterns are literals with masks, used to represent values with don't
* cares. Equality comparisons will ignore don't care bits (for example,
* BitPat(0b10?1) === UInt(0b1001) and UInt(0b1011)).
*/
sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) {
def getWidth: Int = width
def === (other: UInt): Bool = UInt(value) === (other & UInt(mask))
def != (other: UInt): Bool = !(this === other)
}
|