2012-02-26 02:09:26 +01:00
|
|
|
package rocket
|
2011-11-09 23:52:17 +01:00
|
|
|
|
|
|
|
import Chisel._
|
2013-06-13 19:31:04 +02:00
|
|
|
import scala.math._
|
2012-01-14 00:55:56 +01:00
|
|
|
|
2012-10-12 01:48:51 +02:00
|
|
|
object Util
|
2011-12-09 09:42:43 +01:00
|
|
|
{
|
2013-08-12 19:39:11 +02:00
|
|
|
implicit def intToUInt(x: Int): UInt = UInt(x)
|
2012-10-12 01:48:51 +02:00
|
|
|
implicit def intToBoolean(x: Int): Boolean = if (x != 0) true else false
|
|
|
|
implicit def booleanToInt(x: Boolean): Int = if (x) 1 else 0
|
2012-11-26 04:46:48 +01:00
|
|
|
implicit def booleanToBool(x: Boolean): Bits = Bool(x)
|
2012-11-17 15:48:44 +01:00
|
|
|
|
2013-08-12 19:39:11 +02:00
|
|
|
implicit def wcToUInt(c: WideCounter): UInt = c.value
|
2012-11-17 15:48:44 +01:00
|
|
|
}
|
|
|
|
|
2012-11-25 03:19:28 +01:00
|
|
|
object AVec
|
|
|
|
{
|
2013-08-12 19:39:11 +02:00
|
|
|
def apply[T <: Data](elts: Seq[T]): Vec[T] = Vec(elts)
|
2012-11-27 05:34:30 +01:00
|
|
|
def apply[T <: Data](elts: Vec[T]): Vec[T] = apply(elts.toSeq)
|
2012-11-25 03:19:28 +01:00
|
|
|
def apply[T <: Data](elt0: T, elts: T*): Vec[T] = apply(elt0 :: elts.toList)
|
2012-12-12 00:58:53 +01:00
|
|
|
|
|
|
|
def tabulate[T <: Data](n: Int)(f: Int => T): Vec[T] =
|
|
|
|
apply((0 until n).map(i => f(i)))
|
|
|
|
def tabulate[T <: Data](n1: Int, n2: Int)(f: (Int, Int) => T): Vec[Vec[T]] =
|
|
|
|
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
|
2012-11-25 03:19:28 +01:00
|
|
|
}
|
|
|
|
|
2013-06-13 19:31:04 +02:00
|
|
|
object Str
|
|
|
|
{
|
|
|
|
def apply(s: String): Bits = {
|
|
|
|
var i = BigInt(0)
|
|
|
|
require(s.forall(validChar _))
|
|
|
|
for (c <- s)
|
|
|
|
i = (i << 8) | c
|
|
|
|
Lit(i, s.length*8){Bits()}
|
|
|
|
}
|
|
|
|
def apply(x: Char): Bits = {
|
|
|
|
require(validChar(x))
|
|
|
|
Lit(x, 8){Bits()}
|
|
|
|
}
|
2013-08-12 19:39:11 +02:00
|
|
|
def apply(x: UInt): Bits = apply(x, 10)
|
|
|
|
def apply(x: UInt, radix: Int): Bits = {
|
|
|
|
val rad = UInt(radix)
|
2013-06-13 19:31:04 +02:00
|
|
|
val digs = digits(radix)
|
|
|
|
val w = x.getWidth
|
|
|
|
require(w > 0)
|
|
|
|
|
|
|
|
var q = x
|
|
|
|
var s = digs(q % rad)
|
|
|
|
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
|
|
|
q = q / rad
|
2013-08-12 19:39:11 +02:00
|
|
|
s = Cat(Mux(Bool(radix == 10) && q === UInt(0), Str(' '), digs(q % rad)), s)
|
2013-06-13 19:31:04 +02:00
|
|
|
}
|
|
|
|
s
|
|
|
|
}
|
2013-08-12 19:39:11 +02:00
|
|
|
def apply(x: SInt): Bits = apply(x, 10)
|
|
|
|
def apply(x: SInt, radix: Int): Bits = {
|
|
|
|
val neg = x < SInt(0)
|
2013-06-15 09:45:53 +02:00
|
|
|
val abs = x.abs
|
2013-06-13 19:31:04 +02:00
|
|
|
if (radix != 10) {
|
|
|
|
Cat(Mux(neg, Str('-'), Str(' ')), Str(abs, radix))
|
|
|
|
} else {
|
2013-08-12 19:39:11 +02:00
|
|
|
val rad = UInt(radix)
|
2013-06-13 19:31:04 +02:00
|
|
|
val digs = digits(radix)
|
|
|
|
val w = abs.getWidth
|
|
|
|
require(w > 0)
|
|
|
|
|
|
|
|
var q = abs
|
|
|
|
var s = digs(q % rad)
|
|
|
|
var needSign = neg
|
|
|
|
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
|
|
|
q = q / rad
|
2013-08-12 19:39:11 +02:00
|
|
|
val placeSpace = q === UInt(0)
|
2013-06-13 19:31:04 +02:00
|
|
|
val space = Mux(needSign, Str('-'), Str(' '))
|
|
|
|
needSign = needSign && !placeSpace
|
|
|
|
s = Cat(Mux(placeSpace, space, digs(q % rad)), s)
|
|
|
|
}
|
|
|
|
Cat(Mux(needSign, Str('-'), Str(' ')), s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private def digit(d: Int): Char = (if (d < 10) '0'+d else 'a'-10+d).toChar
|
|
|
|
private def digits(radix: Int): Vec[Bits] =
|
|
|
|
AVec((0 until radix).map(i => Str(digit(i))))
|
|
|
|
|
|
|
|
private def validChar(x: Char) = x == (x & 0xFF)
|
|
|
|
}
|
|
|
|
|
2013-01-06 14:18:33 +01:00
|
|
|
object Split
|
|
|
|
{
|
|
|
|
// is there a better way to do do this?
|
|
|
|
def apply(x: Bits, n0: Int) = {
|
|
|
|
val w = checkWidth(x, n0)
|
|
|
|
(x(w-1,n0), x(n0-1,0))
|
|
|
|
}
|
|
|
|
def apply(x: Bits, n1: Int, n0: Int) = {
|
|
|
|
val w = checkWidth(x, n1, n0)
|
|
|
|
(x(w-1,n1), x(n1-1,n0), x(n0-1,0))
|
|
|
|
}
|
|
|
|
def apply(x: Bits, n2: Int, n1: Int, n0: Int) = {
|
|
|
|
val w = checkWidth(x, n2, n1, n0)
|
|
|
|
(x(w-1,n2), x(n2-1,n1), x(n1-1,n0), x(n0-1,0))
|
|
|
|
}
|
|
|
|
|
|
|
|
private def checkWidth(x: Bits, n: Int*) = {
|
|
|
|
val w = x.getWidth
|
|
|
|
def decreasing(x: Seq[Int]): Boolean =
|
|
|
|
if (x.tail.isEmpty) true
|
|
|
|
else x.head > x.tail.head && decreasing(x.tail)
|
|
|
|
require(decreasing(w :: n.toList))
|
|
|
|
w
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-17 15:48:44 +01:00
|
|
|
// a counter that clock gates most of its MSBs using the LSB carry-out
|
|
|
|
case class WideCounter(width: Int, inc: Bool = Bool(true))
|
|
|
|
{
|
|
|
|
private val isWide = width >= 4
|
|
|
|
private val smallWidth = if (isWide) log2Up(width) else width
|
2013-08-16 00:28:15 +02:00
|
|
|
private val small = Reg(init=UInt(0, smallWidth))
|
2013-08-12 19:39:11 +02:00
|
|
|
private val nextSmall = small + UInt(1, smallWidth+1)
|
2012-11-17 15:48:44 +01:00
|
|
|
when (inc) { small := nextSmall(smallWidth-1,0) }
|
|
|
|
|
|
|
|
private val large = if (isWide) {
|
2013-08-16 00:28:15 +02:00
|
|
|
val r = Reg(init=UInt(0, width - smallWidth))
|
2013-08-12 19:39:11 +02:00
|
|
|
when (inc && nextSmall(smallWidth)) { r := r + UInt(1) }
|
2012-11-17 15:48:44 +01:00
|
|
|
r
|
|
|
|
} else null
|
|
|
|
|
|
|
|
val value = Cat(large, small)
|
|
|
|
|
2013-08-12 19:39:11 +02:00
|
|
|
def := (x: UInt) = {
|
2012-11-17 15:48:44 +01:00
|
|
|
val w = x.getWidth
|
|
|
|
small := x(w.min(smallWidth)-1,0)
|
2013-08-12 19:39:11 +02:00
|
|
|
if (isWide) large := (if (w < smallWidth) UInt(0) else x(w.min(width)-1,smallWidth))
|
2012-11-17 15:48:44 +01:00
|
|
|
}
|
2011-12-09 09:42:43 +01:00
|
|
|
}
|