1
0
Fork 0

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:
Howard Mao 2016-09-27 21:27:07 -07:00
parent 0924f8adb0
commit 9910c69c67
53 changed files with 242 additions and 268 deletions

View File

@ -11,7 +11,7 @@ import uncore.devices._
import uncore.util._
import uncore.converters._
import rocket._
import rocket.Util._
import util._
/** Number of memory channels */
case object NMemoryChannels extends Field[Int]

View File

@ -10,7 +10,7 @@ import uncore.agents._
import uncore.devices._
import uncore.converters._
import rocket._
import rocket.Util._
import util._
import util.ConfigUtils._
import rocketchip.{GlobalAddrMap, NCoreplexExtClients}
import cde.{Parameters, Config, Dump, Knob, CDEMatchError}

View File

@ -5,6 +5,7 @@ import cde.{Parameters, Field}
import junctions._
import uncore.tilelink._
import uncore.util._
import util._
import rocket._
trait DirectConnection {

View File

@ -4,7 +4,7 @@ import Chisel._
import uncore.tilelink._
import uncore.agents._
import uncore.coherence.{InnerTLId, OuterTLId}
import uncore.util._
import util._
import junctions.HasAddrMapParameters
import cde.Parameters

View File

@ -4,7 +4,7 @@ import Chisel._
import uncore.tilelink._
import uncore.constants._
import uncore.agents._
import uncore.util._
import util._
import cde.{Parameters, Field}
class CacheFillTest(implicit p: Parameters) extends GroundTest()(p)

View File

@ -4,9 +4,8 @@ import Chisel._
import uncore.tilelink._
import uncore.constants._
import uncore.agents._
import uncore.util._
import util._
import junctions.HasAddrMapParameters
import util.{ParameterizedBundle, SimpleTimer}
import rocket.HellaCacheIO
import cde.{Parameters, Field}

View File

@ -4,7 +4,7 @@ package junctions
import Chisel._
import scala.math.max
import scala.collection.mutable.ArraySeq
import util.{ParameterizedBundle, HellaPeekingArbiter}
import util._
import cde.{Parameters, Field}
case object NastiKey extends Field[NastiParameters]

View File

@ -3,8 +3,7 @@
package rocket
import Chisel._
import Util._
import uncore.util._
import util._
import cde.Parameters
class BPControl(implicit p: Parameters) extends CoreBundle()(p) {

View File

@ -4,10 +4,8 @@ package rocket
import Chisel._
import cde.{Parameters, Field}
import Util._
import uncore.util._
import util._
import uncore.agents.PseudoLRU
import util.ParameterizedBundle
case object BtbKey extends Field[BtbParameters]

View File

@ -3,12 +3,10 @@
package rocket
import Chisel._
import Util._
import uncore.util._
import Instructions._
import cde.{Parameters, Field}
import uncore.devices._
import uncore.util._
import util._
import junctions.AddrMap
class MStatus extends Bundle {

View File

@ -7,10 +7,10 @@ import junctions._
import uncore.tilelink._
import uncore.agents._
import uncore.coherence._
import uncore.util._
import uncore.constants._
import uncore.util._
import util._
import cde.{Parameters, Field}
import Util._
class DCacheDataReq(implicit p: Parameters) extends L1HellaCacheBundle()(p) {
val addr = Bits(width = untagBits)

View File

@ -4,10 +4,9 @@ package rocket
import Chisel._
import Instructions._
import Util._
import util._
import FPConstants._
import uncore.constants.MemoryOpConstants._
import uncore.util._
import cde.{Parameters, Field}
case class FPUConfig(

View File

@ -2,7 +2,7 @@ package rocket
import Chisel._
import uncore.tilelink._
import Util._
import util._
import cde.{Parameters, Field}
class FrontendReq(implicit p: Parameters) extends CoreBundle()(p) {

View File

@ -3,9 +3,8 @@
package rocket
import Chisel._
import Util._
import util._
import cde.{Parameters, Field}
import util.ParameterizedBundle
class Instruction(implicit val p: Parameters) extends ParameterizedBundle with HasCoreParameters {
val pf0 = Bool() // page fault on first half of instruction

View File

@ -4,7 +4,7 @@ import Chisel._
import uncore.agents._
import uncore.tilelink._
import uncore.util._
import Util._
import util._
import cde.{Parameters, Field}
trait HasL1CacheParameters extends HasCacheParameters with HasCoreParameters {

View File

@ -7,7 +7,7 @@ import Instructions._
import uncore.constants.MemoryOpConstants._
import ALU._
import cde.Parameters
import Util._
import util._
abstract trait DecodeConstants extends HasCoreParameters
{

View File

@ -4,7 +4,7 @@ package rocket
import Chisel._
import ALU._
import Util._
import util._
class MultiplierReq(dataBits: Int, tagBits: Int) extends Bundle {
val fn = Bits(width = SZ_ALU_FN)

View File

@ -6,11 +6,10 @@ import Chisel._
import uncore.tilelink._
import uncore.coherence._
import uncore.agents._
import uncore.util._
import uncore.constants._
import util.{ParameterizedBundle, DecoupledHelper}
import uncore.util._
import util._
import cde.{Parameters, Field}
import Util._
case class DCacheConfig(
nMSHRs: Int = 1,

View File

@ -5,8 +5,7 @@ package rocket
import Chisel._
import uncore.agents._
import uncore.constants._
import Util._
import uncore.util._
import util._
import cde.{Parameters, Field}
class PTWReq(implicit p: Parameters) extends CoreBundle()(p) {

View File

@ -6,7 +6,7 @@ import Chisel._
import uncore.tilelink._
import uncore.constants._
import uncore.agents.CacheName
import Util._
import util._
import cde.{Parameters, Field}
case object RoccMaxTaggedMemXacts extends Field[Int]

View File

@ -7,8 +7,7 @@ import uncore.devices._
import uncore.agents.CacheName
import uncore.constants._
import junctions.HasAddrMapParameters
import util.ParameterizedBundle
import Util._
import util._
import cde.{Parameters, Field}
case object XLen extends Field[Int]

View File

@ -2,9 +2,8 @@ package rocket
import Chisel._
import Chisel.ImplicitConversions._
import Util._
import util._
import cde.Parameters
import uncore.util._
class ExpandedInstruction extends Bundle {
val bits = UInt(width = 32)

View File

@ -7,7 +7,7 @@ import uncore.tilelink._
import uncore.agents._
import uncore.converters._
import uncore.devices._
import Util._
import util._
import cde.{Parameters, Field}
case object BuildRoCC extends Field[Seq[RoccParameters]]

View File

@ -3,13 +3,12 @@
package rocket
import Chisel._
import Util._
import util._
import junctions._
import scala.math._
import cde.{Parameters, Field}
import uncore.agents.PseudoLRU
import uncore.coherence._
import uncore.util._
case object PgLevels extends Field[Int]
case object ASIdBits extends Field[Int]

View File

@ -1,177 +0,0 @@
// See LICENSE for license details.
package rocket
import Chisel._
import uncore.util._
import scala.math._
import cde.{Parameters, Field}
object Util {
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
implicit def intToUInt(x: Int): UInt = UInt(x)
implicit def bigIntToUInt(x: BigInt): UInt = UInt(x)
implicit def booleanToBool(x: Boolean): Bits = Bool(x)
implicit def intSeqToUIntSeq(x: Seq[Int]): Seq[UInt] = x.map(UInt(_))
implicit def wcToUInt(c: WideCounter): UInt = c.value
implicit class UIntToAugmentedUInt(val x: UInt) extends AnyVal {
def sextTo(n: Int): UInt =
if (x.getWidth == n) x
else Cat(Fill(n - x.getWidth, x(x.getWidth-1)), x)
def extract(hi: Int, lo: Int): UInt = {
if (hi == lo-1) UInt(0)
else x(hi, lo)
}
}
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 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))
}
import Util._
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
}
}
// a counter that clock gates most of its MSBs using the LSB carry-out
case class WideCounter(width: Int, inc: UInt = UInt(1), reset: Boolean = true)
{
private val isWide = width > 2*inc.getWidth
private val smallWidth = if (isWide) inc.getWidth max log2Up(width) else width
private val small = if (reset) Reg(init=UInt(0, smallWidth)) else Reg(UInt(width = smallWidth))
private val nextSmall = small +& inc
small := nextSmall
private val large = if (isWide) {
val r = if (reset) Reg(init=UInt(0, width - smallWidth)) else Reg(UInt(width = width - smallWidth))
when (nextSmall(smallWidth)) { r := r +& UInt(1) }
r
} else null
val value = if (isWide) Cat(large, small) else small
lazy val carryOut = {
val lo = (small ^ nextSmall) >> 1
if (!isWide) lo else {
val hi = Mux(nextSmall(smallWidth), large ^ (large +& UInt(1)), UInt(0)) >> 1
Cat(hi, lo)
}
}
def := (x: UInt) = {
small := x
if (isWide) large := x >> smallWidth
}
}
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))
}

View File

@ -8,9 +8,8 @@ import junctions._
import uncore.tilelink._
import uncore.tilelink2._
import uncore.devices._
import util.{ParameterizedBundle, ConfigStringOutput, GraphMLOutput}
import util._
import rocket._
import rocket.Util._
import coreplex._
// the following parameters will be refactored properly with TL2

View File

@ -5,12 +5,12 @@ package rocketchip
import Chisel._
import junctions._
import rocket._
import rocket.Util._
import uncore.agents._
import uncore.tilelink._
import uncore.tilelink2.{LazyModule}
import uncore.devices._
import uncore.converters._
import util._
import coreplex._
import scala.math.max
import scala.collection.mutable.{LinkedHashSet, ListBuffer}

View File

@ -3,6 +3,7 @@ package rocketchip
import Chisel._
import uncore.devices.{DebugBusIO, AsyncDebugBusTo, AsyncDebugBusFrom, DebugBusReq, DebugBusResp, DMKey}
import junctions._
import util._
import cde.{Parameters, Field}
case object IncludeJtagDTM extends Field[Boolean]

View File

@ -12,7 +12,7 @@ import uncore.converters._
import uncore.devices._
import uncore.agents._
import uncore.util._
import rocket.Util._
import util._
import rocket.XLen
import scala.math.max
import coreplex._

View File

@ -4,8 +4,7 @@ package rocketchip
import Chisel._
import cde.{Parameters, Field}
import rocket.Util._
import util.LatencyPipe
import util._
import junctions._
import junctions.NastiConstants._

View File

@ -6,9 +6,9 @@ import cde.{Parameters, Dump}
import junctions._
import uncore.devices._
import rocket._
import rocket.Util._
import coreplex._
import uncore.tilelink2._
import util._
import java.nio.file.{Files, Paths}
import java.nio.{ByteBuffer, ByteOrder}

View File

@ -5,11 +5,11 @@ package uncore.agents
import Chisel._
import cde.{Parameters, Field}
import junctions.PAddrBits
import util.ParameterizedBundle
import uncore.tilelink._
import uncore.converters._
import uncore.coherence._
import uncore.util._
import util._
case object NReleaseTransactors extends Field[Int]
case object NProbeTransactors extends Field[Int]

View File

@ -7,6 +7,7 @@ import uncore.coherence._
import uncore.tilelink._
import uncore.constants._
import uncore.util._
import util._
import cde.Parameters
class L2BroadcastHub(implicit p: Parameters) extends HierarchicalCoherenceAgent()(p) {

View File

@ -11,6 +11,7 @@ import uncore.coherence._
import uncore.tilelink._
import uncore.constants._
import uncore.util._
import util._
import cde.{Parameters, Field}
case object CacheName extends Field[String]

View File

@ -3,7 +3,7 @@
package uncore.agents
import Chisel._
import uncore.util._
import util._
abstract class Decoding
{

View File

@ -6,8 +6,7 @@ import Chisel._
import uncore.coherence._
import uncore.tilelink._
import uncore.util._
import uncore.util._
import util.ParameterizedBundle
import util._
import cde.{Field, Parameters}
import scala.math.max

View File

@ -5,7 +5,7 @@ package uncore.coherence
import Chisel._
import uncore.tilelink._
import uncore.constants._
import uncore.util._
import util._
/** The entire CoherencePolicy API consists of the following three traits:
* HasCustomTileLinkMessageTypes, used to define custom messages

View File

@ -6,6 +6,7 @@ import unittest.UnitTest
import junctions._
import uncore.tilelink._
import uncore.util._
import util._
import HastiConstants._
class BRAMSlave(depth: Int)(implicit val p: Parameters) extends Module

View File

@ -5,8 +5,7 @@ package uncore.devices
import Chisel._
import junctions._
import uncore.tilelink._
import uncore.util._
import util.ParameterizedBundle
import util._
import cde.{Parameters, Config, Field}
// *****************************************

View File

@ -3,11 +3,11 @@
package uncore.devices
import Chisel._
import rocket.Util._
import junctions._
import junctions.NastiConstants._
import uncore.tilelink2._
import uncore.util._
import util._
import scala.math.{min,max}
import cde.{Parameters, Field}

View File

@ -1,7 +1,7 @@
package uncore.tilelink
import Chisel._
import junctions._
import util._
object AsyncClientUncachedTileLinkCrossing {
def apply(from_clock: Clock, from_reset: Bool, from_source: ClientUncachedTileLinkIO, to_clock: Clock, to_reset: Bool, depth: Int = 8, sync: Int = 3): ClientUncachedTileLinkIO = {

View File

@ -4,9 +4,9 @@ package uncore.tilelink
import Chisel._
import junctions._
import uncore.coherence.CoherencePolicy
import uncore.util._
import scala.math.max
import uncore.constants._
import util._
import scala.math.max
import cde.{Parameters, Field}
case object CacheBlockOffsetBits extends Field[Int]

View File

@ -4,6 +4,7 @@ import Chisel._
import junctions._
import uncore.constants._
import uncore.util._
import util._
import cde.Parameters
abstract class Driver(implicit p: Parameters) extends TLModule()(p) {

View File

@ -4,7 +4,7 @@ package uncore.tilelink2
import Chisel._
import chisel3.internal.sourceinfo.SourceInfo
import junctions._
import util._
class TLAsyncCrossing(depth: Int = 8, sync: Int = 3) extends LazyModule
{

View File

@ -4,7 +4,7 @@ package uncore.tilelink2
import Chisel._
import chisel3.util.{Irrevocable, IrrevocableIO}
import uncore.util.{SimpleRegIO}
import util.{SimpleRegIO}
case class RegReadFn private(combinational: Boolean, fn: (Bool, Bool) => (Bool, Bool, UInt))
object RegReadFn

View File

@ -4,8 +4,7 @@ package uncore.tilelink2
import Chisel._
import chisel3.util.{Irrevocable, IrrevocableIO}
import junctions._
import uncore.util.{AsyncResetRegVec}
import util.{AsyncResetRegVec, AsyncQueue, AsyncScope}
// A very simple flow control state machine, run in the specified clock domain
class BusyRegisterCrossing(clock: Clock, reset: Bool)

View File

@ -1,25 +0,0 @@
package uncore
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 = {
if (x.size == 1) {
x.head
} else {
val half = 1 << (log2Ceil(x.size) - 1)
val newIdx = idx & UInt(half - 1)
Mux(idx >= UInt(half), x.drop(half)(newIdx), x.take(half)(newIdx))
}
}
def asUInt(): UInt = Cat(x.map(_.asUInt).reverse)
}
}

View File

@ -1,8 +1,7 @@
// See LICENSE for license details.
package junctions
package util
import Chisel._
import uncore.util.{AsyncResetRegVec, AsyncResetReg}
object GrayCounter {
def apply(bits: Int, increment: Bool = Bool(true)): UInt = {
@ -18,11 +17,10 @@ object AsyncGrayCounter {
val syncv = List.fill(sync)(Module (new AsyncResetRegVec(w = in.getWidth, 0)))
syncv.last.io.d := in
syncv.last.io.en := Bool(true)
(syncv.init zip syncv.tail).foreach { case (sink, source) => {
(syncv.init zip syncv.tail).foreach { case (sink, source) =>
sink.io.d := source.io.q
sink.io.en := Bool(true)
}
}
syncv(0).io.d
}
}

View File

@ -1,4 +1,4 @@
package uncore.util
package util
import Chisel._

View File

@ -2,6 +2,7 @@ package util
import Chisel._
import cde.Parameters
import scala.math.max
// Produces 0-width value when counting to 1
class ZCounter(val n: Int) {
@ -34,3 +35,33 @@ object TwoWayCounter {
cnt
}
}
// a counter that clock gates most of its MSBs using the LSB carry-out
case class WideCounter(width: Int, inc: UInt = UInt(1), reset: Boolean = true)
{
private val isWide = width > 2*inc.getWidth
private val smallWidth = if (isWide) inc.getWidth max log2Up(width) else width
private val small = if (reset) Reg(init=UInt(0, smallWidth)) else Reg(UInt(width = smallWidth))
private val nextSmall = small +& inc
small := nextSmall
private val large = if (isWide) {
val r = if (reset) Reg(init=UInt(0, width - smallWidth)) else Reg(UInt(width = width - smallWidth))
when (nextSmall(smallWidth)) { r := r +& UInt(1) }
r
} else null
val value = if (isWide) Cat(large, small) else small
lazy val carryOut = {
val lo = (small ^ nextSmall) >> 1
if (!isWide) lo else {
val hi = Mux(nextSmall(smallWidth), large ^ (large +& UInt(1)), UInt(0)) >> 1
Cat(hi, lo)
}
}
def := (x: UInt) = {
small := x
if (isWide) large := x >> smallWidth
}
}

View File

@ -1,4 +1,4 @@
package junctions
package util
import Chisel._
import chisel3.util.{DecoupledIO, Decoupled, Irrevocable, IrrevocableIO, ReadyValidIO}

View File

@ -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))
}

View File

@ -0,0 +1,48 @@
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 = {
if (x.size == 1) {
x.head
} else {
val half = 1 << (log2Ceil(x.size) - 1)
val newIdx = idx & UInt(half - 1)
Mux(idx >= UInt(half), x.drop(half)(newIdx), x.take(half)(newIdx))
}
}
def asUInt(): UInt = Cat(x.map(_.asUInt).reverse)
}
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
implicit def intToUInt(x: Int): UInt = UInt(x)
implicit def bigIntToUInt(x: BigInt): UInt = UInt(x)
implicit def booleanToBool(x: Boolean): Bits = Bool(x)
implicit def intSeqToUIntSeq(x: Seq[Int]): Seq[UInt] = x.map(UInt(_))
implicit def wcToUInt(c: WideCounter): UInt = c.value
implicit class UIntToAugmentedUInt(val x: UInt) extends AnyVal {
def sextTo(n: Int): UInt =
if (x.getWidth == n) x
else Cat(Fill(n - x.getWidth, x(x.getWidth-1)), x)
def extract(hi: Int, lo: Int): UInt = {
if (hi == lo-1) UInt(0)
else x(hi, lo)
}
}
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
}
}