diff options
Diffstat (limited to 'core/src/main/scala/chisel3/Printable.scala')
| -rw-r--r-- | core/src/main/scala/chisel3/Printable.scala | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/core/src/main/scala/chisel3/Printable.scala b/core/src/main/scala/chisel3/Printable.scala index 006286f9..c477716b 100644 --- a/core/src/main/scala/chisel3/Printable.scala +++ b/core/src/main/scala/chisel3/Printable.scala @@ -6,10 +6,7 @@ import chisel3.internal.firrtl.Component import scala.collection.mutable -import java.util.{ - MissingFormatArgumentException, - UnknownFormatConversionException -} +import java.util.{MissingFormatArgumentException, UnknownFormatConversionException} /** Superclass of things that can be printed in the resulting circuit * @@ -47,17 +44,21 @@ import java.util.{ // 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 * have names */ def unpack(ctx: Component): (String, Iterable[String]) + /** Allow for appending Printables like Strings */ final def +(that: Printable): Printables = Printables(List(this, that)) + /** Allow for appending Strings to Printables */ final def +(that: String): Printables = Printables(List(this, PString(that))) } object Printable { + /** Pack standard printf fmt, args* style into Printable */ def pack(fmt: String, data: Data*): Printable = { @@ -68,11 +69,11 @@ object Printable { def errorMsg(index: Int) = s"""| fmt = "$fmt" | ${carrotAt(index)} - | data = ${data mkString ", "}""".stripMargin + | data = ${data.mkString(", ")}""".stripMargin def getArg(i: Int): Data = { if (!args.hasNext) { val msg = "has no matching argument!\n" + errorMsg(i) - // Exception wraps msg in s"Format Specifier '$msg'" + // Exception wraps msg in s"Format Specifier '$msg'" throw new MissingFormatArgumentException(msg) } args.next() @@ -85,14 +86,14 @@ object Printable { if (percent) { val arg = c match { case FirrtlFormat(x) => FirrtlFormat(x.toString, getArg(i)) - case 'n' => Name(getArg(i)) - case 'N' => FullName(getArg(i)) - case '%' => Percent + case 'n' => Name(getArg(i)) + case 'N' => FullName(getArg(i)) + case '%' => Percent case x => val msg = s"Illegal format specifier '$x'!\n" + errorMsg(i) throw new UnknownFormatConversionException(msg) } - pables += PString(str dropRight 1) // remove format % + pables += PString(str.dropRight(1)) // remove format % pables += arg str = "" percent = false @@ -105,9 +106,11 @@ object Printable { val msg = s"Trailing %\n" + errorMsg(fmt.size - 1) throw new UnknownFormatConversionException(msg) } - require(!args.hasNext, + require( + !args.hasNext, s"Too many arguments! More format specifier(s) expected!\n" + - errorMsg(fmt.size)) + errorMsg(fmt.size) + ) pables += PString(str) Printables(pables) @@ -117,15 +120,17 @@ object Printable { case class Printables(pables: Iterable[Printable]) extends Printable { require(pables.hasDefiniteSize, "Infinite-sized iterables are not supported!") final def unpack(ctx: Component): (String, Iterable[String]) = { - val (fmts, args) = pables.map(_ unpack ctx).unzip + val (fmts, args) = pables.map(_.unpack(ctx)).unzip (fmts.mkString, args.flatten) } } + /** Wrapper for printing Scala Strings */ case class PString(str: String) extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = - (str replaceAll ("%", "%%"), List.empty) + (str.replaceAll("%", "%%"), List.empty) } + /** Superclass for Firrtl format specifiers for Bits */ sealed abstract class FirrtlFormat(private[chisel3] val specifier: Char) extends Printable { def bits: Bits @@ -137,7 +142,7 @@ object FirrtlFormat { final val legalSpecifiers = List('d', 'x', 'b', 'c') def unapply(x: Char): Option[Char] = - Option(x) filter (x => legalSpecifiers contains x) + Option(x).filter(x => legalSpecifiers contains x) /** Helper for constructing Firrtl Formats * Accepts data to simplify pack @@ -152,26 +157,33 @@ object FirrtlFormat { case "x" => Hexadecimal(bits) case "b" => Binary(bits) case "c" => Character(bits) - case c => throw new Exception(s"Illegal format specifier '$c'!") + case c => throw new Exception(s"Illegal format specifier '$c'!") } } } + /** Format bits as Decimal */ case class Decimal(bits: Bits) extends FirrtlFormat('d') + /** Format bits as Hexidecimal */ case class Hexadecimal(bits: Bits) extends FirrtlFormat('x') + /** Format bits as Binary */ case class Binary(bits: Bits) extends FirrtlFormat('b') + /** Format bits as Character */ case class Character(bits: Bits) extends FirrtlFormat('c') + /** Put innermost name (eg. field of bundle) */ case class Name(data: Data) extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = (data.ref.name, List.empty) } + /** Put full name within parent namespace (eg. bundleName.field) */ case class FullName(data: Data) extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = (data.ref.fullName(ctx), List.empty) } + /** Represents escaped percents */ case object Percent extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = ("%%", List.empty) |
