diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/Chisel/Core.scala | 29 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Enum.scala | 9 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Literal.scala | 201 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Tester.scala | 2 |
4 files changed, 36 insertions, 205 deletions
diff --git a/src/main/scala/Chisel/Core.scala b/src/main/scala/Chisel/Core.scala index 5ed249c7..10ebb45b 100644 --- a/src/main/scala/Chisel/Core.scala +++ b/src/main/scala/Chisel/Core.scala @@ -527,13 +527,24 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] { // } // } -import Literal._ - object BitPat { + private def parse(x: String): (BigInt, BigInt, Int) = { + require(x.head == 'b', "BINARY BitPats ONLY") + var bits = BigInt(0) + var mask = BigInt(0) + for (d <- x.tail) { + if (d != '_') { + if (!"01?".contains(d)) ChiselError.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) + } + def apply(n: String): BitPat = { - require(n(0) == 'b', "BINARY BitPats ONLY") - val (bits, mask, swidth) = parseLit(n.substring(1)) - new BitPat(toLitVal(bits, 2), toLitVal(mask, 2), swidth) + val (bits, mask, width) = parse(n) + new BitPat(bits, mask, width) } def DC(width: Int): BitPat = BitPat("b" + ("?" * width)) @@ -769,13 +780,13 @@ trait UIntFactory { def apply(dir: Direction = OUTPUT, width: Int = -1) = new UInt(dir, width) def apply(value: BigInt, width: Int) = { - val w = if (width == -1) (1 max bitLength(value)) else width + val w = if (width == -1) (1 max value.bitLength) else width new UInt(NO_DIR, w, Some(ULit(value, w))) } def apply(value: BigInt): UInt = apply(value, -1) def apply(n: String, width: Int): UInt = { val bitsPerDigit = if (n(0) == 'b') 1 else if (n(0) == 'h') 4 else -1 - apply(stringToVal(n(0), n.substring(1, n.length)), + apply(Literal.stringToVal(n(0), n.substring(1, n.length)), if (width == -1) (bitsPerDigit * (n.length-1)) else width) } def apply(n: String): UInt = apply(n, -1) @@ -841,12 +852,12 @@ object SInt { def apply(dir: Direction = OUTPUT, width: Int = -1) = new SInt(dir, width) def apply(value: BigInt, width: Int) = { - val w = if (width == -1) bitLength(value) + 1 else width + val w = if (width == -1) 1 + value.bitLength else width new SInt(NO_DIR, w, Some(SLit(value, w))) } def apply(value: BigInt): SInt = apply(value, -1) def apply(n: String, width: Int): SInt = - apply(stringToVal(n(0), n.substring(1, n.length)), width) + apply(Literal.stringToVal(n(0), n.substring(1, n.length)), width) def apply(n: String): SInt = apply(n, -1) } diff --git a/src/main/scala/Chisel/Enum.scala b/src/main/scala/Chisel/Enum.scala index 3bc24220..8da9954d 100644 --- a/src/main/scala/Chisel/Enum.scala +++ b/src/main/scala/Chisel/Enum.scala @@ -32,13 +32,16 @@ package Chisel import Literal._ object Enum { + private def makeLit[T <: Bits](nodeType: T, i: Int, n: Int) = + nodeType.cloneType.makeLit(i, BigInt(n-1).bitLength) + /** create n enum values of given type */ - def apply[T <: Bits](nodeType: T, n: Int): List[T] = (Range(0, n, 1).map(x => (Lit(x, sizeof(n-1))(nodeType)))).toList; + def apply[T <: Bits](nodeType: T, n: Int): List[T] = Range(0, n).map(x => makeLit(nodeType, x, n)).toList /** create enum values of given type and names */ - def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l.toList zip (Range(0, l.length, 1).map(x => Lit(x, sizeof(l.length-1))(nodeType)))).toMap; + def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l.toList zip (Range(0, l.length).map(x => makeLit(nodeType, x, l.length)))).toMap /** create enum values of given type and names */ - def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip (Range(0, l.length, 1).map(x => Lit(x, sizeof(l.length-1))(nodeType)))).toMap; + def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip (Range(0, l.length).map(x => makeLit(nodeType, x, l.length)))).toMap } diff --git a/src/main/scala/Chisel/Literal.scala b/src/main/scala/Chisel/Literal.scala index fff2780b..a8e28103 100644 --- a/src/main/scala/Chisel/Literal.scala +++ b/src/main/scala/Chisel/Literal.scala @@ -1,199 +1,16 @@ package Chisel -import scala.math.log -import scala.math.abs -import scala.math.ceil -import scala.math.max -import scala.math.min -import Literal._ -import ChiselError._ - -/* Factory for literal values to be used by Bits and SInt factories. */ -object Lit { - def apply[T <: Bits](n: String)(gen: => T): T = { - makeLit(Literal(n, -1))(gen) - } - - def apply[T <: Bits](n: String, width: Int)(gen: => T): T = { - makeLit(Literal(n, width))(gen) - } - - def apply[T <: Bits](n: String, base: Char)(gen: => T): T = { - makeLit(Literal(-1, base, n))(gen) - } - - def apply[T <: Bits](n: String, base: Char, width: Int)(gen: => T): T = { - makeLit(Literal(width, base, n))(gen) - } - - def apply[T <: Bits](n: BigInt)(gen: => T): T = { - makeLit(Literal(n, signed = gen.isInstanceOf[SInt]))(gen) - } - - def apply[T <: Bits](n: BigInt, width: Int)(gen: => T): T = { - val lit = Literal(n, width, signed = gen.isInstanceOf[SInt]) - makeLit(lit)(gen) - } - - def makeLit[T <: Bits](x: Literal)(gen: => T): T = { - gen.makeLit(x.value, x.width) - } -} - -class Literal(val value: BigInt, val width: Int) { } object Literal { + def sizeof(x: BigInt): Int = x.bitLength - private def bigMax(x: BigInt, y: BigInt): BigInt = if (x > y) x else y; - def sizeof(x: BigInt): Int = { - val y = bigMax(BigInt(1), x.abs).toDouble; - val res = max(1, (ceil(log(y + 1)/log(2.0))).toInt); - res - } - - private def sizeof(base: Char, x: String): Int = { - var res = 0; - var first = true; - val size = - if(base == 'b') { - 1 - } else if(base == 'h') { - 4 - } else if(base == 'o') { - 3 - } else { - -1 - } - for(c <- x) - if (c == '_') { - - } else if(first) { - first = false; - res += sizeof(c.asDigit); - } else if (c != '_') { - res += size; - } - res - } - val hexNibbles = "0123456789abcdef"; - def toHexNibble(x: String, off: Int): Char = { - var res = 0; - for (i <- 0 until 4) { - val idx = off + i; - val c = if (idx < 0) '0' else x(idx); - res = 2 * res + (if (c == '1') 1 else 0); - } - hexNibbles(res) - } - val pads = Vector(0, 3, 2, 1); - def toHex(x: String): String = { - var res = ""; - val numNibbles = (x.length-1) / 4 + 1; - val pad = pads(x.length % 4); - for (i <- 0 until numNibbles) { - res += toHexNibble(x, i*4 - pad); - } - res - } - def toLitVal(x: String): BigInt = { - BigInt(x.substring(2, x.length), 16) - } - - def toLitVal(x: String, shamt: Int): BigInt = { - var res = BigInt(0); - for(c <- x) - if(c != '_'){ - if(!(hexNibbles + "?").contains(c.toLower)) ChiselError.error({"Literal: " + x + " contains illegal character: " + c}); - res = res * shamt + c.asDigit; - } - res + def decodeBase(base: Char): Int = base match { + case 'x' | 'h' => 16 + case 'd' => 10 + case 'o' => 8 + case 'b' => 2 + case _ => ChiselError.error("Invalid base " + base); 2 } - def removeUnderscore(x: String): String = { - var res = "" - for(c <- x){ - if(c != '_'){ - res = res + c - } - } - res - } - - def parseLit(x: String): (String, String, Int) = { - var bits = ""; - var mask = ""; - var width = 0; - for (d <- x) { - if (d != '_') { - if(!"01?".contains(d)) ChiselError.error({"Literal: " + x + " contains illegal character: " + d}); - width += 1; - mask = mask + (if (d == '?') "0" else "1"); - bits = bits + (if (d == '?') "0" else d.toString); - } - } - (bits, mask, width) - } - def stringToVal(base: Char, x: String): BigInt = { - if(base == 'x') { - toLitVal(x, 16); - } else if(base == 'd') { - BigInt(x.toInt) - } else if(base == 'h') { - toLitVal(x, 16) - } else if(base == 'b') { - toLitVal(x, 2) - } else if(base == 'o') { - toLitVal(x, 8) - } else { - BigInt(-1) - } - } - - /** Derive the bit length for a Literal - * - */ - def bitLength(b: BigInt): Int = { - // Check for signedness - // We have seen unexpected values (one too small) when using .bitLength on negative BigInts, - // so use the positive value instead. - val usePositiveValueForBitLength = false - (if (usePositiveValueForBitLength && b < 0) { - -b - } else { - b - }).bitLength - } - /** Creates a *Literal* instance from a scala integer. - */ - def apply(x: BigInt, width: Int = -1, signed: Boolean = false): Literal = { - // Check for signedness - // We get unexpected values (one too small) when using .bitLength on negative BigInts, - // so use the positive value instead. - val bl = bitLength(x) - val xWidth = if (signed) { - bl + 1 - } else { - max(bl, 1) - } - val w = if(width == -1) xWidth else width - val xString = (if (x >= 0) x else (BigInt(1) << w) + x).toString(16) - - if(xWidth > width && width != -1) { - // Is this a zero-width wire with value 0 - if (!(x == 0 && width == 0 && Driver.isSupportW0W)) { - ChiselError.error({"width " + width + " is too small for literal " + x + ". Smallest allowed width is " + xWidth}); - } - } - apply("h" + xString, w) - } - def apply(n: String, width: Int): Literal = - apply(width, n(0), n.substring(1, n.length)); - - def apply(width: Int, base: Char, literal: String): Literal = { - if (!"dhbo".contains(base)) { - ChiselError.error("no base specified"); - } - new Literal(stringToVal(base, literal), width) - } + def stringToVal(base: Char, x: String): BigInt = + BigInt(x, decodeBase(base)) } - - diff --git a/src/main/scala/Chisel/Tester.scala b/src/main/scala/Chisel/Tester.scala index cf7c7b1c..37923a5f 100644 --- a/src/main/scala/Chisel/Tester.scala +++ b/src/main/scala/Chisel/Tester.scala @@ -178,7 +178,7 @@ class ManualTester[+T <: Module] cmd = "wire_peek " + name; } val s = emulatorCmd(cmd) - val rv = toLitVal(s) + val rv = BigInt(s.substring(2), 16) if (isTrace) println(" PEEK " + name + " " + (if (off >= 0) (off + " ") else "") + "-> " + s) rv } |
