Move a bunch more things into util package
A lot of utility code was just being imported willy-nilly from one package to another. This moves the common code into util to make things more sensible. The code moved were * The AsyncQueue and AsyncDecoupledCrossing from junctions. * All of the code in rocket's util.scala * The BlackBox asynchronous reset registers from uncore.tilelink2 * The implicit definitions from uncore.util
This commit is contained in:
@ -2,6 +2,7 @@ package util
|
||||
|
||||
import Chisel._
|
||||
import cde.Parameters
|
||||
import scala.math._
|
||||
|
||||
class ParameterizedBundle(implicit p: Parameters) extends Bundle {
|
||||
override def cloneType = {
|
||||
@ -26,3 +27,113 @@ class DecoupledHelper(val rvs: Seq[Bool]) {
|
||||
(rvs.filter(_ ne exclude) ++ includes).reduce(_ && _)
|
||||
}
|
||||
}
|
||||
|
||||
object MuxT {
|
||||
def apply[T <: Data, U <: Data](cond: Bool, con: (T, U), alt: (T, U)): (T, U) =
|
||||
(Mux(cond, con._1, alt._1), Mux(cond, con._2, alt._2))
|
||||
|
||||
def apply[T <: Data, U <: Data, W <: Data](cond: Bool, con: (T, U, W), alt: (T, U, W)): (T, U, W) =
|
||||
(Mux(cond, con._1, alt._1), Mux(cond, con._2, alt._2), Mux(cond, con._3, alt._3))
|
||||
}
|
||||
|
||||
object Str
|
||||
{
|
||||
def apply(s: String): UInt = {
|
||||
var i = BigInt(0)
|
||||
require(s.forall(validChar _))
|
||||
for (c <- s)
|
||||
i = (i << 8) | c
|
||||
UInt(i, s.length*8)
|
||||
}
|
||||
def apply(x: Char): UInt = {
|
||||
require(validChar(x))
|
||||
UInt(x.toInt, 8)
|
||||
}
|
||||
def apply(x: UInt): UInt = apply(x, 10)
|
||||
def apply(x: UInt, radix: Int): UInt = {
|
||||
val rad = UInt(radix)
|
||||
val w = x.getWidth
|
||||
require(w > 0)
|
||||
|
||||
var q = x
|
||||
var s = digit(q % rad)
|
||||
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
||||
q = q / rad
|
||||
s = Cat(Mux(Bool(radix == 10) && q === UInt(0), Str(' '), digit(q % rad)), s)
|
||||
}
|
||||
s
|
||||
}
|
||||
def apply(x: SInt): UInt = apply(x, 10)
|
||||
def apply(x: SInt, radix: Int): UInt = {
|
||||
val neg = x < SInt(0)
|
||||
val abs = x.abs
|
||||
if (radix != 10) {
|
||||
Cat(Mux(neg, Str('-'), Str(' ')), Str(abs, radix))
|
||||
} else {
|
||||
val rad = UInt(radix)
|
||||
val w = abs.getWidth
|
||||
require(w > 0)
|
||||
|
||||
var q = abs
|
||||
var s = digit(q % rad)
|
||||
var needSign = neg
|
||||
for (i <- 1 until ceil(log(2)/log(radix)*w).toInt) {
|
||||
q = q / rad
|
||||
val placeSpace = q === UInt(0)
|
||||
val space = Mux(needSign, Str('-'), Str(' '))
|
||||
needSign = needSign && !placeSpace
|
||||
s = Cat(Mux(placeSpace, space, digit(q % rad)), s)
|
||||
}
|
||||
Cat(Mux(needSign, Str('-'), Str(' ')), s)
|
||||
}
|
||||
}
|
||||
|
||||
private def digit(d: UInt): UInt = Mux(d < UInt(10), Str('0')+d, Str(('a'-10).toChar)+d)(7,0)
|
||||
private def validChar(x: Char) = x == (x & 0xFF)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
object Random
|
||||
{
|
||||
def apply(mod: Int, random: UInt): UInt = {
|
||||
if (isPow2(mod)) random(log2Up(mod)-1,0)
|
||||
else PriorityEncoder(partition(apply(1 << log2Up(mod*8), random), mod))
|
||||
}
|
||||
def apply(mod: Int): UInt = apply(mod, randomizer)
|
||||
def oneHot(mod: Int, random: UInt): UInt = {
|
||||
if (isPow2(mod)) UIntToOH(random(log2Up(mod)-1,0))
|
||||
else PriorityEncoderOH(partition(apply(1 << log2Up(mod*8), random), mod)).asUInt
|
||||
}
|
||||
def oneHot(mod: Int): UInt = oneHot(mod, randomizer)
|
||||
|
||||
private def randomizer = LFSR16()
|
||||
private def round(x: Double): Int =
|
||||
if (x.toInt.toDouble == x) x.toInt else (x.toInt + 1) & -2
|
||||
private def partition(value: UInt, slices: Int) =
|
||||
Seq.tabulate(slices)(i => value < round((i << value.getWidth).toDouble / slices))
|
||||
}
|
||||
|
Reference in New Issue
Block a user