From a62d8e4be0a7270cd9339ef99d9fbc90c815c1f2 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 13 Dec 2017 19:50:22 -0800 Subject: [PATCH 1/4] Expand printf documentation --- .../src/main/scala/chisel3/core/Printf.scala | 57 ++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala index 87134eda348..99d0e06e91c 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala @@ -9,6 +9,10 @@ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.SourceInfo +/** Prints a message in simulation + * + * See apply methods for use + */ object printf { // scalastyle:ignore object.name /** Helper for packing escape characters */ private[chisel3] def format(formatIn: String): String = { @@ -28,30 +32,57 @@ object printf { // scalastyle:ignore object.name formatIn map escaped mkString "" } - /** Prints a message in simulation. + /** Prints a message in simulation * - * Does not fire when in reset (defined as the encapsulating Module's - * reset). If your definition of reset is not the encapsulating Module's - * reset, you will need to gate this externally. + * Prints a message every cycle. If defined within the scope of a [[when]] block, the message + * will only be printed on cycles that the when condition is true. * - * May be called outside of a Module (like defined in a function), uses - * whatever clock and reset are in scope. + * Does not fire when in reset (defined as the encapsulating Module's reset). If your definition + * of reset is not the encapsulating Module's reset, you will need to gate this externally. + * + * May be called outside of a Module (like defined in a function), uses the current default clock + * and reset. These can be overriden with [[withClockAndReset]]. + * + * ==Format Strings== + * + * This method expects a ''format string'' and an ''argument list'' in a similar style to printf + * in C. The format string expects a [[scala.Predef.String String]] that may contain ''format + * specifiers'' For example: + * {{{ + * printf("myWire has the value %d\n", myWire) + * }}} + * This prints the string "myWire has the value " followed by the current value of `myWire` (in + * decimal, followed by a newline. + * + * There must be exactly as many arguments as there are format specifiers + * + * ===Format Specifiers=== + * + * Format specifiers are prefixed by `%`. If you wish to print a literal `%`, use `%%`. + * - `%d` - Decimal + * - `%x` - Hexadecimal + * - `%b` - Binary + * - `%c` - 8-bit Character + * - `%n` - Name of a signal + * - `%N` - Full name of a leaf signal (in an aggregate) * * @param fmt printf format string * @param data format string varargs containing data to print */ def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = apply(Printable.pack(fmt, data:_*)) - /** Prints a message in simulation. + /** Prints a message in simulation + * + * Prints a message every cycle. If defined within the scope of a [[when]] block, the message + * will only be printed on cycles that the when condition is true. * - * Does not fire when in reset (defined as the encapsulating Module's - * reset). If your definition of reset is not the encapsulating Module's - * reset, you will need to gate this externally. + * Does not fire when in reset (defined as the encapsulating Module's reset). If your definition + * of reset is not the encapsulating Module's reset, you will need to gate this externally. * - * May be called outside of a Module (like defined in a function), so - * functions using printf make the standard Module assumptions (single clock - * and single reset). + * May be called outside of a Module (like defined in a function), uses the current default clock + * and reset. These can be overriden with [[withClockAndReset]]. * + * @see [[Printable]] documentation * @param pable [[Printable]] to print */ def apply(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { From 1b133bf81a294b61edb07a32987ce9b7fe8ecbaa Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 13 Dec 2017 20:05:58 -0800 Subject: [PATCH 2/4] Expand Printable documentation --- .../main/scala/chisel3/core/Printable.scala | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Printable.scala b/chiselFrontend/src/main/scala/chisel3/core/Printable.scala index f6e63936775..8c35c33a95a 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Printable.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Printable.scala @@ -14,12 +14,39 @@ import java.util.{ /** Superclass of things that can be printed in the resulting circuit * - * Usually created using the custom string interpolator p"..." - * TODO Add support for names of Modules - * Currently impossible because unpack is called before the name is selected - * Could be implemented by adding a new format specifier to Firrtl (eg. %m) - * TODO Should we provide more functions like map and mkPrintable? + * Usually created using the custom string interpolator `p"..."`. Printable string interpolation is + * similar to [[https://docs.scala-lang.org/overviews/core/string-interpolation.html String + * interpolation in Scala]] For example: + * {{{ + * printf(p"The value of wire = \$wire\n") + * }}} + * This is equivalent to writing: + * {{{ + * printf(p"The value of wire = %d\n", wire) + * }}} + * All Chisel data types have a method `.toPrintable` that gives a default pretty print that can be + * accessed via `p"..."`. This works even for aggregate types, for example: + * {{{ + * val myVec = VecInit(5.U, 10.U, 13.U) + * printf(p"myVec = \$myVec\n") + * // myVec = Vec(5, 10, 13) + * + * val myBundle = Wire(new Bundle { + * val foo = UInt() + * val bar = UInt() + * }) + * myBundle.foo := 3.U + * myBundle.bar := 11.U + * printf(p"myBundle = \$myBundle\n") + * // myBundle = Bundle(a -> 3, b -> 11) + * }}} + * Users can override the default behavior of `.toPrintable` in custom [[Bundle]] and [[Record]] + * types. */ +// TODO Add support for names of Modules +// Currently impossible because unpack is called before the name is selected +// Could be implemented by adding a new format specifier to Firrtl (eg. %m) +// TODO Should we provide more functions like map and mkPrintable? sealed abstract class Printable { /** Unpack into format String and a List of String arguments (identifiers) * @note This must be called after elaboration when Chisel nodes actually From 39f280341575b0ec7dd539f2ff009899e8824016 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 13 Dec 2017 20:23:13 -0800 Subject: [PATCH 3/4] Fix some ScalaDoc warnings --- .../src/main/scala/chisel3/core/Aggregate.scala | 14 ++++++++------ .../main/scala/chisel3/core/ChiselAnnotation.scala | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 88cc6ff65b4..a4eeb8a5d19 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -118,11 +118,13 @@ object Vec extends VecFactory /** A vector (array) of [[Data]] elements. Provides hardware versions of various * collection transformation functions found in software array implementations. * - * Careful consideration should be given over the use of [[Vec]] vs [[Seq]] or some other scala collection. In - * general [[Vec]] only needs to be used when there is a need to express the hardware collection in a [[Reg]] - * or IO [[Bundle]] or when access to elements of the array is indexed via a hardware signal. + * Careful consideration should be given over the use of [[Vec]] vs + * [[scala.collection.immutable.Seq Seq]] or some other Scala collection. In general [[Vec]] only + * needs to be used when there is a need to express the hardware collection in a [[Reg]] or IO + * [[Bundle]] or when access to elements of the array is indexed via a hardware signal. * - * Example of indexing into a [[Vec]] using a hardware address and where the [[Vec]] is defined in an IO [[Bundle]] + * Example of indexing into a [[Vec]] using a hardware address and where the [[Vec]] is defined in + * an IO [[Bundle]] * * {{{ * val io = IO(new Bundle { @@ -468,7 +470,7 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio } /** Default "pretty-print" implementation * Analogous to printing a Map - * Results in "$className(elt0.name -> elt0.value, ...)" + * Results in "`\$className(elt0.name -> elt0.value, ...)`" */ def toPrintable: Printable = toPrintableHelper(elements.toList) } @@ -581,7 +583,7 @@ class Bundle(implicit compileOptions: CompileOptions) extends Record { /** Default "pretty-print" implementation * Analogous to printing a Map - * Results in "Bundle(elt0.name -> elt0.value, ...)" + * Results in "`Bundle(elt0.name -> elt0.value, ...)`" * @note The order is reversed from the order of elements in order to print * the fields in the order they were defined */ diff --git a/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala b/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala index 07546406dd4..98253ce55f5 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/ChiselAnnotation.scala @@ -45,9 +45,9 @@ case class ChiselAnnotation(component: InstanceId, transformClass: Class[_ <: Tr * } * }}} * - * @note Calling this on Data creates an annotation that Chisel emits to a separate annotations - * file. This file must be passed to Firrtl independently of the .fir file. - * [[chisel3.Driver.execute]] will do this automatically. + * @note Calling this on [[Data]] creates an annotation that Chisel emits to a separate annotations + * file. This file must be passed to FIRRTL independently of the `.fir` file. The execute methods + * in [[chisel3.Driver]] will pass the annotations to FIRRTL automatically. */ object dontTouch { // scalastyle:ignore object.name /** Marks a signal to be preserved in Chisel and Firrtl From ae7351dd07ea80c381e94c15b857b1fc698ba8ca Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 13 Dec 2017 21:13:52 -0800 Subject: [PATCH 4/4] Improve some of the ScalaDoc in chisel3.util --- src/main/scala/chisel3/util/Conditional.scala | 1 + src/main/scala/chisel3/util/Counter.scala | 21 ++++++------ src/main/scala/chisel3/util/Enum.scala | 34 ++++++++++++------- .../chisel3/util/ImplicitConversions.scala | 3 ++ src/main/scala/chisel3/util/Valid.scala | 16 +++++---- src/main/scala/chisel3/util/util.scala | 4 +-- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala index 3ebda69bbe5..860ffde3983 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -22,6 +22,7 @@ object unless { // scalastyle:ignore object.name /** Implementation details for [[switch]]. See [[switch]] and [[chisel3.util.is is]] for the * user-facing API. + * @note DO NOT USE. This API is subject to change without warning. */ class SwitchContext[T <: Bits](cond: T, whenContext: Option[WhenContext], lits: Set[BigInt]) { def is(v: Iterable[T])(block: => Unit): SwitchContext[T] = { diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index aa0c0d43c8f..f6f99f67fe1 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -4,10 +4,19 @@ package chisel3.util import chisel3._ import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order -//import chisel3.core.ExplicitCompileOptions.Strict /** A counter module - * + * + * Typically instantiated with apply methods in [[Counter$ object Counter]] + * + * @example {{{ + * val countOn = true.B // increment counter every clock cycle + * val (counterValue, counterWrap) = Counter(countOn, 4) + * when (counterValue === 3.U) { + * ... + * } + * }}} + * * @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 */ @@ -46,14 +55,6 @@ object Counter * @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 = true.B // increment counter every clock cycle - * val (counterValue, counterWrap) = Counter(countOn, 4) - * when (counterValue === 3.U) { - * ... - * } - * }}} */ @chiselName def apply(cond: Bool, n: Int): (UInt, Bool) = { diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala index 6ed0d42242e..2fdd1a92cfb 100644 --- a/src/main/scala/chisel3/util/Enum.scala +++ b/src/main/scala/chisel3/util/Enum.scala @@ -7,25 +7,33 @@ package chisel3.util import chisel3._ +/** Defines a set of unique UInt constants + * + * Unpack with a list to specify an enumeration. Usually used with [[switch]] to describe a finite + * state machine. + * + * @example {{{ + * val state_on :: state_off :: Nil = Enum(2) + * val current_state = WireInit(state_off) + * switch (current_state) { + * is (state_on) { + * ... + * } + * is (state_off) { + * ... + * } + * } + * }}} + */ trait Enum { /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ protected def createValues(n: Int): Seq[UInt] = (0 until n).map(_.U((1 max log2Ceil(n)).W)) - /** Returns n unique UInt values, use with unpacking to specify an enumeration. + /** Returns n unique UInt values * - * @example {{{ - * val state_on :: state_off :: Nil = Enum(2) - * val current_state = UInt() - * switch (current_state) { - * is (state_on) { - * ... - * } - * if (state_off) { - * ... - * } - * } - * }}} + * @param n Number of unique UInt constants to enumerate + * @return Enumerated constants */ def apply(n: Int): List[UInt] = createValues(n).toList } diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 712975a79e3..994ac735698 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -6,6 +6,9 @@ import chisel3._ import scala.language.implicitConversions +/** Implicit conversions to automatically convert [[scala.Boolean]] and [[scala.Int]] to [[Bool]] + * and [[UInt]] respectively + */ object ImplicitConversions { // The explicit fromIntToLiteral resolves an ambiguous conversion between fromIntToLiteral and // UInt.asUInt. diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 7017b7a1c8e..95f0dceab4f 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -24,13 +24,15 @@ object Valid { } /** A hardware module that delays data coming down the pipeline - by the number of cycles set by the latency parameter. Functionality - is similar to ShiftRegister but this exposes a Pipe interface. - - Example usage: - val pipe = new Pipe(UInt()) - pipe.io.enq <> produce.io.out - consumer.io.in <> pipe.io.deq + * by the number of cycles set by the latency parameter. Functionality + * is similar to ShiftRegister but this exposes a Pipe interface. + * + * Example usage: + * {{{ + * val pipe = new Pipe(UInt()) + * pipe.io.enq <> produce.io.out + * consumer.io.in <> pipe.io.deq + * }}} */ object Pipe { diff --git a/src/main/scala/chisel3/util/util.scala b/src/main/scala/chisel3/util/util.scala index 129e5d1a75b..987678e36d1 100644 --- a/src/main/scala/chisel3/util/util.scala +++ b/src/main/scala/chisel3/util/util.scala @@ -2,8 +2,8 @@ package chisel3 -/** The util package provides extensions to core chisel for common hardware components and utility functions. - * +/** The util package provides extensions to core chisel for common hardware components and utility + * functions */ package object util {