summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/Printf.scala
diff options
context:
space:
mode:
authorJack Koenig2016-09-07 14:18:29 -0700
committerGitHub2016-09-07 14:18:29 -0700
commit0ed5eb48cdb916b644aaf9e5dbf48f6cfb6c60f4 (patch)
tree71829e27aa3c57e682c8231c27027b3efbd2918d /chiselFrontend/src/main/scala/chisel3/core/Printf.scala
parent16426b3a68d85ce7dd9655b0ce773431eb69fc74 (diff)
Add Printable (#270)
Printable is a new type that changes how printing of Chisel types is represented It uses an ordered collection rather than a format string and specifiers Features: - Custom String Interpolator for Scala-like printf - String-like manipulation of "hardware strings" for custom pretty-printing - Default pretty-printing for Chisel data types
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Printf.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Printf.scala44
1 files changed, 39 insertions, 5 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala
index b0a3c955..55197425 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala
@@ -10,6 +10,24 @@ import chisel3.internal.firrtl._
import chisel3.internal.sourceinfo.SourceInfo
object printf { // scalastyle:ignore object.name
+ /** Helper for packing escape characters */
+ private[chisel3] def format(formatIn: String): String = {
+ require(formatIn forall (c => c.toInt > 0 && c.toInt < 128),
+ "format strings must comprise non-null ASCII values")
+ def escaped(x: Char) = {
+ require(x.toInt >= 0)
+ if (x == '"' || x == '\\') {
+ s"\\${x}"
+ } else if (x == '\n') {
+ "\\n"
+ } else {
+ require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved
+ x
+ }
+ }
+ formatIn map escaped mkString ""
+ }
+
/** Prints a message in simulation.
*
* Does not fire when in reset (defined as the encapsulating Module's
@@ -23,14 +41,30 @@ object printf { // scalastyle:ignore object.name
* @param fmt printf format string
* @param data format string varargs containing data to print
*/
- def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo) {
- when (!(Builder.dynamicContext.currentModule.get.reset)) {
- printfWithoutReset(fmt, data:_*)
+ def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo): Unit =
+ apply(Printable.pack(fmt, data:_*))
+ /** 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.
+ *
+ * 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).
+ *
+ * @param pable [[Printable]] to print
+ */
+ def apply(pable: Printable)(implicit sourceInfo: SourceInfo): Unit = {
+ when (!Builder.dynamicContext.currentModule.get.reset) {
+ printfWithoutReset(pable)
}
}
- private[core] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo) {
+ private[chisel3] def printfWithoutReset(pable: Printable)(implicit sourceInfo: SourceInfo): Unit = {
val clock = Builder.dynamicContext.currentModule.get.clock
- pushCommand(Printf(sourceInfo, Node(clock), fmt, data.map((d: Bits) => d.ref)))
+ pushCommand(Printf(sourceInfo, Node(clock), pable))
}
+ private[chisel3] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo): Unit =
+ printfWithoutReset(Printable.pack(fmt, data:_*))
}