summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Lawson2016-09-23 08:19:43 -0700
committerGitHub2016-09-23 08:19:43 -0700
commit785620b1403d827986bf60c2a001d8d6f71eed72 (patch)
tree1c1a0b14b041e544da3ff8176aba200604a131b3 /src
parentb18e98ba2d058c7dd24f96f005486b70c856aeca (diff)
parentdecb2ee0f0bb8223f0b2b067b88ed90b71473a28 (diff)
Merge pull request #291 from ucb-bar/utilscaladocs
Scaladocs for utils
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/chisel3/util/Arbiter.scala45
-rw-r--r--src/main/scala/chisel3/util/BitPat.scala2
-rw-r--r--src/main/scala/chisel3/util/Bitwise.scala26
-rw-r--r--src/main/scala/chisel3/util/Cat.scala13
-rw-r--r--src/main/scala/chisel3/util/CircuitMath.scala14
-rw-r--r--src/main/scala/chisel3/util/Conditional.scala51
-rw-r--r--src/main/scala/chisel3/util/Counter.scala25
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala42
-rw-r--r--src/main/scala/chisel3/util/Enum.scala36
-rw-r--r--src/main/scala/chisel3/util/LFSR.scala13
-rw-r--r--src/main/scala/chisel3/util/Mux.scala23
-rw-r--r--src/main/scala/chisel3/util/OneHot.scala24
-rw-r--r--src/main/scala/chisel3/util/Reg.scala38
13 files changed, 226 insertions, 126 deletions
diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala
index eb541977..58ba1188 100644
--- a/src/main/scala/chisel3/util/Arbiter.scala
+++ b/src/main/scala/chisel3/util/Arbiter.scala
@@ -7,16 +7,21 @@ package chisel3.util
import chisel3._
-/** An I/O bundle for the Arbiter */
+/** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs
+ * (selects) at most one.
+ *
+ * @param gen data type
+ * @param n number of inputs
+ */
class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle {
val in = Vec(n, Decoupled(gen)).flip
val out = Decoupled(gen)
val chosen = UInt(OUTPUT, log2Up(n))
}
-/** Arbiter Control determining which producer has access */
-private object ArbiterCtrl
-{
+/** Arbiter Control determining which producer has access
+ */
+private object ArbiterCtrl {
def apply(request: Seq[Bool]): Seq[Bool] = request.length match {
case 0 => Seq()
case 1 => Seq(Bool(true))
@@ -81,25 +86,27 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T
}
/** Hardware module that is used to sequence n producers into 1 consumer.
- Producers are chosen in round robin order.
-
- Example usage:
- val arb = new RRArbiter(2, UInt())
- arb.io.in(0) <> producer0.io.out
- arb.io.in(1) <> producer1.io.out
- consumer.io.in <> arb.io.out
+ * Producers are chosen in round robin order.
+ *
+ * @example {{{
+ * val arb = new RRArbiter(2, UInt())
+ * arb.io.in(0) <> producer0.io.out
+ * arb.io.in(1) <> producer1.io.out
+ * consumer.io.in <> arb.io.out
+ * }}}
*/
class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1)
/** Hardware module that is used to sequence n producers into 1 consumer.
- Priority is given to lower producer
-
- Example usage:
- val arb = Module(new Arbiter(2, UInt()))
- arb.io.in(0) <> producer0.io.out
- arb.io.in(1) <> producer1.io.out
- consumer.io.in <> arb.io.out
- */
+ * Priority is given to lower producer.
+ *
+ * @example {{{
+ * val arb = Module(new Arbiter(2, UInt()))
+ * arb.io.in(0) <> producer0.io.out
+ * arb.io.in(1) <> producer1.io.out
+ * consumer.io.in <> arb.io.out
+ * }}}
+ */
class Arbiter[T <: Data](gen: T, n: Int) extends Module {
val io = new ArbiterIO(gen, n)
diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala
index 26106080..6c012583 100644
--- a/src/main/scala/chisel3/util/BitPat.scala
+++ b/src/main/scala/chisel3/util/BitPat.scala
@@ -37,7 +37,7 @@ object BitPat {
/** Creates a [[BitPat]] literal from a string.
*
* @param n the literal value as a string, in binary, prefixed with 'b'
- * @note legal characters are '0', '1', and '?', as well as '_' as white
+ * @note legal characters are '0', '1', and '?', as well as '_' and white
* space (which are ignored)
*/
def apply(n: String): BitPat = {
diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala
index 6451ab14..7d5ffe09 100644
--- a/src/main/scala/chisel3/util/Bitwise.scala
+++ b/src/main/scala/chisel3/util/Bitwise.scala
@@ -8,9 +8,18 @@ package chisel3.util
import chisel3._
import chisel3.core.SeqUtils
-object FillInterleaved
-{
+object FillInterleaved {
+ /** Creates n repetitions of each bit of x in order.
+ *
+ * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times)
+ * For example, FillInterleaved(2, "b1000") === UInt("b11 00 00 00")
+ */
def apply(n: Int, in: UInt): UInt = apply(n, in.toBools)
+
+ /** Creates n repetitions of each bit of x in order.
+ *
+ * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times)
+ */
def apply(n: Int, in: Seq[Bool]): UInt = Cat(in.map(Fill(n, _)).reverse)
}
@@ -22,9 +31,11 @@ object PopCount
def apply(in: Bits): UInt = apply((0 until in.getWidth).map(in(_)))
}
-/** Fill fans out a UInt to multiple copies */
object Fill {
- /** Fan out x n times */
+ /** Create n repetitions of x using a tree fanout topology.
+ *
+ * Output data-equivalent to x ## x ## ... ## x (n repetitions).
+ */
def apply(n: Int, x: UInt): UInt = {
n match {
case 0 => UInt(width=0)
@@ -42,10 +53,7 @@ object Fill {
}
}
-/** Litte/big bit endian convertion: reverse the order of the bits in a UInt.
-*/
-object Reverse
-{
+object Reverse {
private def doit(in: UInt, length: Int): UInt = {
if (length == 1) {
in
@@ -65,5 +73,7 @@ object Reverse
Cat(doit(in(half-1,0), half), doit(in(length-1,half), length-half))
}
}
+ /** Returns the input in bit-reversed order. Useful for little/big-endian conversion.
+ */
def apply(in: UInt): UInt = doit(in, in.getWidth)
}
diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala
index 469bf9ab..ba12a7d4 100644
--- a/src/main/scala/chisel3/util/Cat.scala
+++ b/src/main/scala/chisel3/util/Cat.scala
@@ -6,16 +6,15 @@ import chisel3._
import chisel3.core.SeqUtils
object Cat {
- /** Combine data elements together
- * @param a Data to combine with
- * @param r any number of other Data elements to be combined in order
- * @return A UInt which is all of the bits combined together
+ /** Concatenates the argument data elements, in argument order, together.
*/
def apply[T <: Bits](a: T, r: T*): UInt = apply(a :: r.toList)
- /** Combine data elements together
- * @param r any number of other Data elements to be combined in order
- * @return A UInt which is all of the bits combined together
+ /** Concatenates the data elements of the input sequence, in reverse sequence order, together.
+ * The first element of the sequence forms the most significant bits, while the last element
+ * in the sequence forms the least significant bits.
+ *
+ * Equivalent to r(0) ## r(1) ## ... ## r(n-1).
*/
def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse)
}
diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala
index a64447d9..d478e10e 100644
--- a/src/main/scala/chisel3/util/CircuitMath.scala
+++ b/src/main/scala/chisel3/util/CircuitMath.scala
@@ -7,13 +7,11 @@ package chisel3.util
import chisel3._
-/** Compute the base-2 integer logarithm of a UInt
- * @example
- * {{{ data_out := Log2(data_in) }}}
- * @note The result is truncated, so e.g. Log2(UInt(13)) = 3
- */
object Log2 {
- /** Compute the Log2 on the least significant n bits of x */
+ /** Returns the base-2 integer logarithm of the least-significant `width` bits of an UInt.
+ *
+ * @note The result is truncated, so e.g. Log2(UInt(13)) === UInt(3)
+ */
def apply(x: Bits, width: Int): UInt = {
if (width < 2) {
UInt(0)
@@ -30,6 +28,10 @@ object Log2 {
}
}
+ /** Returns the base-2 integer logarithm of an UInt.
+ *
+ * @note The result is truncated, so e.g. Log2(UInt(13)) === UInt(3)
+ */
def apply(x: Bits): UInt = apply(x, x.getWidth)
private def divideAndConquerThreshold = 4
diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala
index 6218feb0..5830e014 100644
--- a/src/main/scala/chisel3/util/Conditional.scala
+++ b/src/main/scala/chisel3/util/Conditional.scala
@@ -12,50 +12,71 @@ import scala.reflect.macros.blackbox._
import chisel3._
-/** This is identical to [[Chisel.when when]] with the condition inverted */
object unless { // scalastyle:ignore object.name
+ /** Does the same thing as [[when$ when]], but with the condition inverted.
+ */
def apply(c: Bool)(block: => Unit) {
when (!c) { block }
}
}
+/** Implementation details for [[switch]]. See [[switch]] and [[chisel3.util.is is]] for the
+ * user-facing API.
+ */
class SwitchContext[T <: Bits](cond: T) {
def is(v: Iterable[T])(block: => Unit) {
- if (!v.isEmpty) when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) { block }
+ if (!v.isEmpty) {
+ when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) {
+ block
+ }
+ }
}
def is(v: T)(block: => Unit) { is(Seq(v))(block) }
def is(v: T, vr: T*)(block: => Unit) { is(v :: vr.toList)(block) }
}
-/** An object for separate cases in [[Chisel.switch switch]]
- * It is equivalent to a [[Chisel.when$ when]] block comparing to the condition
- * Use outside of a switch statement is illegal */
+/** Use to specify cases in a [[switch]] block, equivalent to a [[when$ when]] block comparing to
+ * the condition variable.
+ *
+ * @note illegal outside a [[switch]] block
+ * @note multiple conditions may fire simultaneously
+ * @note dummy implementation, a macro inside [[switch]] transforms this into the actual
+ * implementation
+ */
object is { // scalastyle:ignore object.name
- // Begin deprecation of non-type-parameterized is statements.
+ // TODO: Begin deprecation of non-type-parameterized is statements.
+ /** Executes `block` if the switch condition is equal to any of the values in `v`.
+ */
def apply(v: Iterable[Bits])(block: => Unit) {
require(false, "The 'is' keyword may not be used outside of a switch.")
}
+ /** Executes `block` if the switch condition is equal to `v`.
+ */
def apply(v: Bits)(block: => Unit) {
require(false, "The 'is' keyword may not be used outside of a switch.")
}
+ /** Executes `block` if the switch condition is equal to any of the values in the argument list.
+ */
def apply(v: Bits, vr: Bits*)(block: => Unit) {
require(false, "The 'is' keyword may not be used outside of a switch.")
}
}
-/** Conditional logic to form a switch block
- * @example
- * {{{ ... // default values here
- * switch ( myState ) {
- * is( state1 ) {
- * ... // some logic here
+/** Conditional logic to form a switch block. See [[is$ is]] for the case API.
+ *
+ * @example {{{
+ * switch (myState) {
+ * is (state1) {
+ * // some logic here that runs when myState === state1
* }
- * is( state2 ) {
- * ... // some logic here
+ * is (state2) {
+ * // some logic here that runs when myState === state2
* }
- * } }}}*/
+ * }
+ * }}}
+ */
object switch { // scalastyle:ignore object.name
def apply[T <: Bits](cond: T)(x: => Unit): Unit = macro impl
def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { import c.universe._
diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala
index 1c95190b..4b20158f 100644
--- a/src/main/scala/chisel3/util/Counter.scala
+++ b/src/main/scala/chisel3/util/Counter.scala
@@ -5,12 +5,14 @@ package chisel3.util
import chisel3._
/** A counter module
+ *
* @param n number of counts before the counter resets (or one more than the
* maximum output value of the counter), need not be a power of two
*/
class Counter(val n: Int) {
require(n >= 0)
val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0)
+
/** Increment the counter, returning whether the counter currently is at the
* maximum and will wrap. The incremented value is registered and will be
* visible on the next cycle.
@@ -29,14 +31,27 @@ class Counter(val n: Int) {
}
}
-/** Counter Object
- * Example Usage:
- * {{{ val countOn = Bool(true) // increment counter every clock cycle
- * val (myCounterValue, myCounterWrap) = Counter(countOn, n)
- * when ( myCounterValue === UInt(3) ) { ... } }}}*/
object Counter
{
+ /** Instantiate a [[Counter! counter]] with the specified number of counts.
+ */
def apply(n: Int): Counter = new Counter(n)
+
+ /** Instantiate a [[Counter! counter]] with the specified number of counts and a gate.
+ *
+ * @param cond condition that controls whether the counter increments this cycle
+ * @param n number of counts before the counter resets
+ * @return tuple of the counter value and whether the counter will wrap (the value is at
+ * maximum and the condition is true).
+ *
+ * @example {{{
+ * val countOn = Bool(true) // increment counter every clock cycle
+ * val (counterValue, counterWrap) = Counter(countOn, 4)
+ * when (counterValue === UInt(3)) {
+ * ...
+ * }
+ * }}}
+ */
def apply(cond: Bool, n: Int): (UInt, Bool) = {
val c = new Counter(n)
var wrap: Bool = null
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index 77990777..65558aa9 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -21,10 +21,10 @@ abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle
def fire(dummy: Int = 0): Bool = ready && valid
}
-/** A concrete subclass of ReadyValidIO signalling that the user expects a
+/** A concrete subclass of ReadyValidIO signaling that the user expects a
* "decoupled" interface: 'valid' indicates that the producer has
* put valid data in 'bits', and 'ready' indicates that the consumer is ready
- * to accept the data this cycle. No requirements are placed on the signalling
+ * to accept the data this cycle. No requirements are placed on the signaling
* of ready or valid.
*/
class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen)
@@ -35,12 +35,12 @@ class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen)
/** This factory adds a decoupled handshaking protocol to a data bundle. */
object Decoupled
{
- /** Take any Data and wrap it in a DecoupledIO interface */
+ /** Wraps some Data with a DecoupledIO interface. */
def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen)
- /** Take an IrrevocableIO and cast it to a DecoupledIO.
- * This cast is only safe to do in cases where the IrrevocableIO
- * is being produced as an output.
+ /** Downconverts an IrrevocableIO output to a DecoupledIO, dropping guarantees of irrevocability.
+ *
+ * @note unsafe (and will error) on the producer (input) side of an IrrevocableIO
*/
def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = {
require(irr.bits.dir == OUTPUT, "Only safe to cast produced Irrevocable bits to Decoupled.")
@@ -67,9 +67,10 @@ object Irrevocable
{
def apply[T <: Data](gen: T): IrrevocableIO[T] = new IrrevocableIO(gen)
- /** Take a DecoupledIO and cast it to an IrrevocableIO.
- * This cast is only safe to do in cases where the IrrevocableIO
- * is being consumed as an input.
+ /** Upconverts a DecoupledIO input to an IrrevocableIO, allowing an IrrevocableIO to be used
+ * where a DecoupledIO is expected.
+ *
+ * @note unsafe (and will error) on the consumer (output) side of an DecoupledIO
*/
def apply[T <: Data](dec: DecoupledIO[T]): IrrevocableIO[T] = {
require(dec.bits.dir == INPUT, "Only safe to cast consumed Decoupled bits to Irrevocable.")
@@ -156,10 +157,11 @@ class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle
* @param flow True if the inputs can be consumed on the same cycle (the inputs "flow" through the queue immediately).
* The ''valid'' signals are coupled.
*
- * Example usage:
- * {{{ val q = new Queue(UInt(), 16)
- * q.io.enq <> producer.io.out
- * consumer.io.in <> q.io.deq }}}
+ * @example {{{
+ * val q = new Queue(UInt(), 16)
+ * q.io.enq <> producer.io.out
+ * consumer.io.in <> q.io.deq
+ * }}}
*/
class Queue[T <: Data](gen: T,
val entries: Int,
@@ -223,12 +225,16 @@ extends Module(override_reset=override_reset) {
}
}
-/** Factory for a generic hardware queue. Required parameter 'entries' controls
- * the depth of the queues. The width of the queue is determined
- * from the input 'enq'.
+/** Factory for a generic hardware queue.
*
- * Example usage:
- * {{{ consumer.io.in <> Queue(producer.io.out, 16) }}}
+ * @param enq input (enqueue) interface to the queue, also determines width of queue elements
+ * @param entries depth (number of elements) of the queue
+ *
+ * @returns output (dequeue) interface from the queue
+ *
+ * @example {{{
+ * consumer.io.in <> Queue(producer.io.out, 16)
+ * }}}
*/
object Queue
{
diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala
index 4ecc243b..55b595ee 100644
--- a/src/main/scala/chisel3/util/Enum.scala
+++ b/src/main/scala/chisel3/util/Enum.scala
@@ -12,12 +12,42 @@ object Enum {
private def createValues[T <: Bits](nodeType: T, n: Int): Seq[T] =
(0 until n).map(x => nodeType.fromInt(x, log2Up(n)))
- /** create n enum values of given type */
+ /** Returns n unique values of the specified type. Can be used with unpacking to define enums.
+ *
+ * @example {{{
+ * val state_on :: state_off :: Nil = Enum(UInt(), 2)
+ * val current_state = UInt()
+ * switch (current_state) {
+ * is (state_on) {
+ * ...
+ * }
+ * if (state_off) {
+ * ...
+ * }
+ * }
+ * }}}
+ *
+ */
def apply[T <: Bits](nodeType: T, n: Int): List[T] = createValues(nodeType, n).toList
- /** create enum values of given type and names */
+ /** Returns a map of the input symbols to unique values of the specified type.
+ *
+ * @example {{{
+ * val states = Enum(UInt(), 'on, 'off)
+ * val current_state = UInt()
+ * switch (current_state) {
+ * is (states('on)) {
+ * ...
+ * }
+ * if (states('off)) {
+ * ..
+ * }
+ * }
+ * }}}
+ */
def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap
- /** create enum values of given type and names */
+ /** Returns a map of the input symbols to unique values of the specified type.
+ */
def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap
}
diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala
index a30c276f..e4261c20 100644
--- a/src/main/scala/chisel3/util/LFSR.scala
+++ b/src/main/scala/chisel3/util/LFSR.scala
@@ -8,12 +8,13 @@ package chisel3.util
import chisel3._
// scalastyle:off magic.number
-/** linear feedback shift register
- */
-object LFSR16
-{
- def apply(increment: Bool = Bool(true)): UInt =
- {
+object LFSR16 {
+ /** Generates a 16-bit linear feedback shift register, returning the register contents.
+ * May be useful for generating a pseudorandom sequence.
+ *
+ * @param increment optional control to gate when the LFSR updates.
+ */
+ def apply(increment: Bool = Bool(true)): UInt = {
val width = 16
val lfsr = Reg(init=UInt(1, width))
when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) }
diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala
index 9956a7e3..245de67e 100644
--- a/src/main/scala/chisel3/util/Mux.scala
+++ b/src/main/scala/chisel3/util/Mux.scala
@@ -9,10 +9,11 @@ import chisel3._
import chisel3.core.SeqUtils
/** Builds a Mux tree out of the input signal vector using a one hot encoded
- select signal. Returns the output of the Mux tree.
+ * select signal. Returns the output of the Mux tree.
+ *
+ * @note results undefined if multiple select signals are simultaneously high
*/
-object Mux1H
-{
+object Mux1H {
def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T =
apply(sel zip in)
def apply[T <: Data](in: Iterable[(Bool, T)]): T = SeqUtils.oneHotMux(in)
@@ -22,18 +23,17 @@ object Mux1H
}
/** Builds a Mux tree under the assumption that multiple select signals
- can be enabled. Priority is given to the first select signal.
-
- Returns the output of the Mux tree.
+ * can be enabled. Priority is given to the first select signal.
+ *
+ * Returns the output of the Mux tree.
*/
-object PriorityMux
-{
+object PriorityMux {
def apply[T <: Data](in: Seq[(Bool, T)]): T = SeqUtils.priorityMux(in)
def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in)
def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in)
}
-/** MuxLookup creates a cascade of n Muxs to search for a key value */
+/** Creates a cascade of n Muxs to search for a key value. */
object MuxLookup {
/** @param key a key to search for
* @param default a default value if nothing is found
@@ -46,10 +46,11 @@ object MuxLookup {
res = Mux(k === key, v, res)
res
}
-
}
-/** MuxCase returns the first value that is enabled in a map of values */
+/** Given an association of values to enable signals, returns the first value with an associated
+ * high enable signal.
+ */
object MuxCase {
/** @param default the default value if none are enabled
* @param mapping a set of data values with associated enables
diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala
index 7e04a8d7..53ba8c3d 100644
--- a/src/main/scala/chisel3/util/OneHot.scala
+++ b/src/main/scala/chisel3/util/OneHot.scala
@@ -7,8 +7,12 @@ package chisel3.util
import chisel3._
-/** Converts from One Hot Encoding to a UInt indicating which bit is active
- * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/
+/** Returns the bit position of the sole high bit of the input bitvector.
+ *
+ * Inverse operation of [[UIntToOH]].
+ *
+ * @note assumes exactly one high bit, results undefined otherwise
+ */
object OHToUInt {
def apply(in: Seq[Bool]): UInt = apply(Cat(in.reverse), in.size)
def apply(in: Vec[Bool]): UInt = apply(in.asUInt, in.size)
@@ -26,9 +30,9 @@ object OHToUInt {
}
}
-/** @return the bit position of the trailing 1 in the input vector
- * with the assumption that multiple bits of the input bit vector can be set
- * @example {{{ data_out := PriorityEncoder(data_in) }}}
+/** Returns the bit position of the least-significant high bit of the input bitvector.
+ *
+ * Multiple bits may be high in the input.
*/
object PriorityEncoder {
def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_)))
@@ -37,8 +41,7 @@ object PriorityEncoder {
/** Returns the one hot encoding of the input UInt.
*/
-object UIntToOH
-{
+object UIntToOH {
def apply(in: UInt, width: Int = -1): UInt =
if (width == -1) {
UInt(1) << in
@@ -47,11 +50,10 @@ object UIntToOH
}
}
-/** Returns a bit vector in which only the least-significant 1 bit in
- the input vector, if any, is set.
+/** Returns a bit vector in which only the least-significant 1 bit in the input vector, if any,
+ * is set.
*/
-object PriorityEncoderOH
-{
+object PriorityEncoderOH {
private def encode(in: Seq[Bool]): UInt = {
val outs = Seq.tabulate(in.size)(i => UInt(BigInt(1) << i, in.size))
PriorityMux(in :+ Bool(true), outs :+ UInt(0, in.size))
diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala
index 81de4754..80a3f43e 100644
--- a/src/main/scala/chisel3/util/Reg.scala
+++ b/src/main/scala/chisel3/util/Reg.scala
@@ -1,34 +1,40 @@
// See LICENSE for license details.
-/** Variations and helpers for registers.
- */
-
package chisel3.util
import chisel3._
object RegNext {
-
+ /** Returns a register with the specified next and no reset initialization.
+ *
+ * Essentially a 1-cycle delayed version of the input signal.
+ */
def apply[T <: Data](next: T): T = Reg[T](null.asInstanceOf[T], next, null.asInstanceOf[T])
+ /** Returns a register with the specified next and reset initialization.
+ *
+ * Essentially a 1-cycle delayed version of the input signal.
+ */
def apply[T <: Data](next: T, init: T): T = Reg[T](null.asInstanceOf[T], next, init)
-
}
object RegInit {
-
+ /** Returns a register pre-initialized (on reset) to the specified value.
+ */
def apply[T <: Data](init: T): T = Reg[T](null.asInstanceOf[T], null.asInstanceOf[T], init)
-
}
-/** A register with an Enable signal */
-object RegEnable
-{
+object RegEnable {
+ /** Returns a register with the specified next, update enable gate, and no reset initialization.
+ */
def apply[T <: Data](updateData: T, enable: Bool): T = {
val r = Reg(updateData)
when (enable) { r := updateData }
r
}
+
+ /** Returns a register with the specified next, update enable gate, and reset initialization.
+ */
def apply[T <: Data](updateData: T, resetData: T, enable: Bool): T = {
val r = RegInit(resetData)
when (enable) { r := updateData }
@@ -36,15 +42,15 @@ object RegEnable
}
}
-/** Returns the n-cycle delayed version of the input signal.
- */
object ShiftRegister
{
- /** @param in input to delay
+ /** Returns the n-cycle delayed version of the input signal.
+ *
+ * @param in input to delay
* @param n number of cycles to delay
- * @param en enable the shift */
- def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T =
- {
+ * @param en enable the shift
+ */
+ def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T = {
// The order of tests reflects the expected use cases.
if (n == 1) {
RegEnable(in, en)