diff options
| author | ducky | 2016-09-21 17:59:38 -0700 |
|---|---|---|
| committer | ducky | 2016-09-21 17:59:38 -0700 |
| commit | 6eb00023fcc3ad77b98e51971f6e193ea506b9cc (patch) | |
| tree | aa187c92e797be7df22bb7e41a39218642b1d237 | |
| parent | a2cb95bfe9e9c30b73284e97048fa0187ab0ee1d (diff) | |
Improved scaladoc in utils and friends
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala | 18 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/Cat.scala | 13 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/CircuitMath.scala | 14 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/Conditional.scala | 50 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/Counter.scala | 25 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/OneHot.scala | 24 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/Reg.scala | 38 |
7 files changed, 119 insertions, 63 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala index 63bcc87f..0d8604cd 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala @@ -7,7 +7,12 @@ import scala.language.experimental.macros import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform} private[chisel3] object SeqUtils { - /** Equivalent to Cat(r(n-1), ..., r(0)) */ + /** Concatenates the data elements of the input sequence, in sequence order, together. + * The first element of the sequence forms the least significant bits, while the last element + * in the sequence forms the most significant bits. + * + * Equivalent to r(n-1) ## ... ## r(1) ## r(0). + */ def asUInt[T <: Bits](in: Seq[T]): UInt = macro SourceInfoTransform.inArg def do_asUInt[T <: Bits](in: Seq[T])(implicit sourceInfo: SourceInfo): UInt = { @@ -20,7 +25,8 @@ private[chisel3] object SeqUtils { } } - /** Counts the number of true Bools in a Seq */ + /** Outputs the number of elements that === Bool(true). + */ def count(in: Seq[Bool]): UInt = macro SourceInfoTransform.inArg def do_count(in: Seq[Bool])(implicit sourceInfo: SourceInfo): UInt = in.size match { @@ -29,7 +35,8 @@ private[chisel3] object SeqUtils { case n => count(in take n/2) +& count(in drop n/2) } - /** Returns data value corresponding to first true predicate */ + /** Returns the data value corresponding to the first true predicate. + */ def priorityMux[T <: Data](in: Seq[(Bool, T)]): T = macro SourceInfoTransform.inArg def do_priorityMux[T <: Data](in: Seq[(Bool, T)])(implicit sourceInfo: SourceInfo): T = { @@ -40,7 +47,10 @@ private[chisel3] object SeqUtils { } } - /** Returns data value corresponding to lone true predicate */ + /** Returns the data value corresponding to the lone true predicate. + * + * @note assumes exactly one true predicate, results undefined otherwise + */ def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)])(implicit sourceInfo: SourceInfo): T = { 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..461ff765 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -12,50 +12,72 @@ 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 +/** Conditional logic to form a switch block. See [[is$ is]] for the case API. + * * @example - * {{{ ... // default values here - * switch ( myState ) { - * is( state1 ) { - * ... // some logic here + * {{{ + * 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/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) |
