1
0
rocket-chip/src/main/scala/util/Package.scala

85 lines
2.7 KiB
Scala
Raw Normal View History

// See LICENSE.SiFive for license details.
import Chisel._
package object util {
implicit class UIntIsOneOf(val x: UInt) extends AnyVal {
def isOneOf(s: Seq[UInt]): Bool = s.map(x === _).reduce(_||_)
def isOneOf(u1: UInt, u2: UInt*): Bool = isOneOf(u1 +: u2.toSeq)
}
implicit class SeqToAugmentedSeq[T <: Data](val x: Seq[T]) extends AnyVal {
def apply(idx: UInt): T = {
2017-04-14 00:54:24 +02:00
if (!isPow2(x.size)) {
// For non-power-of-2 seqs, reflect elements to simplify decoder
(x ++ x.takeRight(x.size & -x.size)).toSeq(idx)
} else {
2017-04-14 00:54:24 +02:00
// Ignore MSBs of idx
val truncIdx =
if (idx.isWidthKnown && idx.getWidth <= log2Ceil(x.size)) idx
else (idx | UInt(0, log2Ceil(x.size)))(log2Ceil(x.size)-1, 0)
(x.head /: x.zipWithIndex.tail) { case (prev, (cur, i)) => Mux(truncIdx === i.U, cur, prev) }
}
}
def asUInt(): UInt = Cat(x.map(_.asUInt).reverse)
}
implicit class DataToAugmentedData[T <: Data](val x: T) extends AnyVal {
def holdUnless(enable: Bool): T = Mux(enable, x, RegEnable(x, enable))
}
implicit class SeqMemToAugmentedSeqMem[T <: Data](val x: SeqMem[T]) extends AnyVal {
def readAndHold(addr: UInt, enable: Bool): T = x.read(addr, enable) holdUnless RegNext(enable)
}
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
implicit def wcToUInt(c: WideCounter): UInt = c.value
implicit class UIntToAugmentedUInt(val x: UInt) extends AnyVal {
2017-04-22 03:01:32 +02:00
def sextTo(n: Int): UInt = {
require(x.getWidth <= n)
if (x.getWidth == n) x
else Cat(Fill(n - x.getWidth, x(x.getWidth-1)), x)
2017-04-22 03:01:32 +02:00
}
def padTo(n: Int): UInt = {
require(x.getWidth <= n)
if (x.getWidth == n) x
else Cat(UInt(0, n - x.getWidth), x)
}
def extract(hi: Int, lo: Int): UInt = {
if (hi == lo-1) UInt(0)
else x(hi, lo)
}
2017-03-09 09:28:19 +01:00
def inRange(base: UInt, bounds: UInt) = x >= base && x < bounds
}
implicit class BooleanToAugmentedBoolean(val x: Boolean) extends AnyVal {
def toInt: Int = if (x) 1 else 0
// this one's snagged from scalaz
def option[T](z: => T): Option[T] = if (x) Some(z) else None
}
object PopCountAtLeast {
private def two(x: UInt): (Bool, Bool) = x.getWidth match {
2016-10-08 06:20:40 +02:00
case 1 => (x.toBool, Bool(false))
case n =>
val half = x.getWidth / 2
val (leftOne, leftTwo) = two(x(half - 1, 0))
val (rightOne, rightTwo) = two(x(x.getWidth - 1, half))
(leftOne || rightOne, leftTwo || rightTwo || (leftOne && rightOne))
}
def apply(x: UInt, n: Int): Bool = n match {
case 0 => Bool(true)
case 1 => x.orR
case 2 => two(x)._2
case 3 => PopCount(x) >= UInt(n)
}
}
}