diff options
| author | Jack Koenig | 2016-09-07 14:18:29 -0700 |
|---|---|---|
| committer | GitHub | 2016-09-07 14:18:29 -0700 |
| commit | 0ed5eb48cdb916b644aaf9e5dbf48f6cfb6c60f4 (patch) | |
| tree | 71829e27aa3c57e682c8231c27027b3efbd2918d /src/main | |
| parent | 16426b3a68d85ce7dd9655b0ce773431eb69fc74 (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 'src/main')
| -rw-r--r-- | src/main/scala/chisel3/internal/firrtl/Emitter.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/chisel3/package.scala | 51 |
2 files changed, 56 insertions, 1 deletions
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 8b94c68f..8ace27f9 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -25,7 +25,11 @@ private class Emitter(circuit: Circuit) { case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}" case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}" case e: Stop => s"stop(${e.clk.fullName(ctx)}, UInt<1>(1), ${e.ret})" - case e: Printf => s"""printf(${e.clk.fullName(ctx)}, UInt<1>(1), "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})""" + case e: Printf => + val (fmt, args) = e.pable.unpack + val printfArgs = Seq(e.clk.fullName(ctx), "UInt<1>(1)", + "\"" + printf.format(fmt) + "\"") ++ args + printfArgs mkString ("printf(", ", ", ")") case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid" case e: DefInstance => s"inst ${e.name} of ${e.id.modName}" case w: WhenBegin => diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 0b548683..30e2b5c3 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -54,6 +54,27 @@ package object chisel3 { val when = chisel3.core.when type WhenContext = chisel3.core.WhenContext + type Printable = chisel3.core.Printable + val Printable = chisel3.core.Printable + type Printables = chisel3.core.Printables + val Printables = chisel3.core.Printables + type PString = chisel3.core.PString + val PString = chisel3.core.PString + type FirrtlFormat = chisel3.core.FirrtlFormat + val FirrtlFormat = chisel3.core.FirrtlFormat + type Decimal = chisel3.core.Decimal + val Decimal = chisel3.core.Decimal + type Hexadecimal = chisel3.core.Hexadecimal + val Hexadecimal = chisel3.core.Hexadecimal + type Binary = chisel3.core.Binary + val Binary = chisel3.core.Binary + type Character = chisel3.core.Character + val Character = chisel3.core.Character + type Name = chisel3.core.Name + val Name = chisel3.core.Name + type FullName = chisel3.core.FullName + val FullName = chisel3.core.FullName + val Percent = chisel3.core.Percent implicit class fromBigIntToLiteral(val x: BigInt) extends AnyVal { def U: UInt = UInt(x, Width()) @@ -79,4 +100,34 @@ package object chisel3 { def do_!= (that: BitPat)(implicit sourceInfo: SourceInfo): Bool = that != x def do_=/= (that: BitPat)(implicit sourceInfo: SourceInfo): Bool = that =/= x } + + /** Implicit for custom Printable string interpolator */ + implicit class PrintableHelper(val sc: StringContext) extends AnyVal { + /** Custom string interpolator for generating Printables: p"..." + * Will call .toString on any non-Printable arguments (mimicking s"...") + */ + def p(args: Any*): Printable = { + sc.checkLengths(args) // Enforce sc.parts.size == pargs.size + 1 + val pargs: Seq[Option[Printable]] = args map { + case p: Printable => Some(p) + case d: Data => Some(d.toPrintable) + case any => for { + v <- Option(any) // Handle null inputs + str = v.toString + if !str.isEmpty // Handle empty Strings + } yield PString(str) + } + val parts = sc.parts map StringContext.treatEscapes + // Zip sc.parts and pargs together ito flat Seq + // eg. Seq(sc.parts(0), pargs(0), sc.parts(1), pargs(1), ...) + val seq = for { // append None because sc.parts.size == pargs.size + 1 + (literal, arg) <- parts zip (pargs :+ None) + optPable <- Seq(Some(PString(literal)), arg) + pable <- optPable // Remove Option[_] + } yield pable + Printables(seq) + } + } + + implicit def string2Printable(str: String): Printable = PString(str) } |
