aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/scala/firrtl/Emitter.scala2
-rw-r--r--src/main/scala/firrtl/Serialize.scala238
-rw-r--r--src/main/scala/firrtl/Utils.scala6
-rw-r--r--src/main/scala/firrtl/WIR.scala102
-rw-r--r--src/main/scala/firrtl/ir/IR.scala207
-rw-r--r--src/main/scala/firrtl/passes/CheckChirrtl.scala1
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala3
-rw-r--r--src/main/scala/firrtl/passes/Passes.scala1
8 files changed, 248 insertions, 312 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala
index 0c0cc36d..d09a4afe 100644
--- a/src/main/scala/firrtl/Emitter.scala
+++ b/src/main/scala/firrtl/Emitter.scala
@@ -36,7 +36,6 @@ import scala.sys.process._
import scala.io.Source
import Utils._
-import firrtl.Serialize._
import firrtl.Mappers._
import firrtl.passes._
import firrtl.PrimOps._
@@ -61,6 +60,7 @@ case class VRandom(width: BigInt) extends Expression {
def tpe = UIntType(IntWidth(width))
def nWords = (width + 31) / 32
def realWidth = nWords * 32
+ def serialize: String = "RANDOM"
}
class VerilogEmitter extends Emitter {
val tab = " "
diff --git a/src/main/scala/firrtl/Serialize.scala b/src/main/scala/firrtl/Serialize.scala
deleted file mode 100644
index d28675b0..00000000
--- a/src/main/scala/firrtl/Serialize.scala
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
-Copyright (c) 2014 - 2016 The Regents of the University of
-California (Regents). All Rights Reserved. Redistribution and use in
-source and binary forms, with or without modification, are permitted
-provided that the following conditions are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- two paragraphs of disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- two paragraphs of disclaimer in the documentation and/or other materials
- provided with the distribution.
- * Neither the name of the Regents nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
-SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
-ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
-REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
-ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
-TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
-MODIFICATIONS.
-*/
-
-package firrtl
-
-import firrtl.ir._
-import firrtl.PrimOps._
-import firrtl.Utils._
-
-private object Serialize {
- def serialize(root: FirrtlNode): String = {
- lazy val ser = new Serialize
- root match {
- case r: PrimOp => ser.serialize(r)
- case r: Expression => ser.serialize(r)
- case r: Statement => ser.serialize(r)
- case r: Width => ser.serialize(r)
- case r: Orientation => ser.serialize(r)
- case r: Field => ser.serialize(r)
- case r: Type => ser.serialize(r)
- case r: Direction => ser.serialize(r)
- case r: Port => ser.serialize(r)
- case r: DefModule => ser.serialize(r)
- case r: Circuit => ser.serialize(r)
- case r: StringLit => ser.serialize(r)
- case _ => throw new Exception("serialize called on unknown FirrtlNode!")
- }
- }
- /** Creates new instance of Serialize */
- def apply() = new Serialize
-}
-
-class Serialize {
- def serialize(bi: BigInt): String =
- if (bi < BigInt(0)) "\"h" + bi.toString(16).substring(1) + "\""
- else "\"h" + bi.toString(16) + "\""
-
- def serialize(info: Info): String = " " + info.toString
-
- def serialize(op: PrimOp): String = op.toString
-
- def serialize(lit: StringLit): String = FIRRTLStringLitHandler.escape(lit)
-
- def serialize(exp: Expression): String = {
- exp match {
- case v: UIntLiteral => s"UInt${serialize(v.width)}(${serialize(v.value)})"
- case v: SIntLiteral => s"SInt${serialize(v.width)}(${serialize(v.value)})"
- case r: Reference => r.name
- case s: SubField => s"${serialize(s.expr)}.${s.name}"
- case s: SubIndex => s"${serialize(s.expr)}[${s.value}]"
- case s: SubAccess => s"${serialize(s.expr)}[${serialize(s.index)}]"
- case m: Mux => s"mux(${serialize(m.cond)}, ${serialize(m.tval)}, ${serialize(m.fval)})"
- case v: ValidIf => s"validif(${serialize(v.cond)}, ${serialize(v.value)})"
- case p: DoPrim =>
- s"${serialize(p.op)}(" + (p.args.map(serialize) ++ p.consts.map(_.toString)).mkString(", ") + ")"
- case r: WRef => r.name
- case s: WSubField => s"${serialize(s.exp)}.${s.name}"
- case s: WSubIndex => s"${serialize(s.exp)}[${s.value}]"
- case s: WSubAccess => s"${serialize(s.exp)}[${serialize(s.index)}]"
- case r: WVoid => "VOID"
- }
- }
-
- def serialize(stmt: Statement): String = {
- stmt match {
- case w: DefWire => s"wire ${w.name} : ${serialize(w.tpe)}${w.info}"
- case r: DefRegister =>
- val str = new StringBuilder(s"reg ${r.name} : ${serialize(r.tpe)}, ${serialize(r.clock)} with :")
- withIndent {
- str ++= newline + s"reset => (${serialize(r.reset)}, ${serialize(r.init)})${r.info}"
- }
- str.toString
- case i: DefInstance => s"inst ${i.name} of ${i.module}${i.info}"
- case i: WDefInstance => s"inst ${i.name} of ${i.module}${i.info}"
- case m: DefMemory => {
- val str = new StringBuilder(s"mem ${m.name} :${m.info}")
- withIndent {
- str ++= newline +
- s"data-type => ${serialize(m.dataType)}" + newline +
- s"depth => ${m.depth}" + newline +
- s"read-latency => ${m.readLatency}" + newline +
- s"write-latency => ${m.writeLatency}" + newline +
- (if (m.readers.nonEmpty) m.readers.map(r => s"reader => ${r}").mkString(newline) + newline
- else "") +
- (if (m.writers.nonEmpty) m.writers.map(w => s"writer => ${w}").mkString(newline) + newline
- else "") +
- (if (m.readwriters.nonEmpty) m.readwriters.map(rw => s"readwriter => ${rw}").mkString(newline) + newline
- else "") +
- s"read-under-write => undefined"
- }
- str.result
- }
- case n: DefNode => s"node ${n.name} = ${serialize(n.value)}${n.info}"
- case c: Connect => s"${serialize(c.loc)} <= ${serialize(c.expr)}${c.info}"
- case p: PartialConnect => s"${serialize(p.loc)} <- ${serialize(p.expr)}${p.info}"
- case w: Conditionally => {
- var str = new StringBuilder(s"when ${serialize(w.pred)} :${w.info}")
- withIndent { str ++= newline + serialize(w.conseq) }
- w.alt match {
- case EmptyStmt => str.result
- case s => {
- str ++= newline + "else :"
- withIndent { str ++= newline + serialize(w.alt) }
- str.result
- }
- }
- }
- case b: Block => {
- val s = new StringBuilder
- for (i <- 0 until b.stmts.size) {
- if (i != 0) s ++= newline ++ serialize(b.stmts(i))
- else s ++= serialize(b.stmts(i))
- }
- s.result
- }
- case i: IsInvalid => s"${serialize(i.expr)} is invalid${i.info}"
- case s: Stop => s"stop(${serialize(s.clk)}, ${serialize(s.en)}, ${s.ret})${s.info}"
- case p: Print => {
- val q = '"'.toString
- s"printf(${serialize(p.clk)}, ${serialize(p.en)}, ${q}${serialize(p.string)}${q}" +
- (if (p.args.nonEmpty) p.args.map(serialize).mkString(", ", ", ", "") else "") +
- s")${p.info}"
- }
- case EmptyStmt => "skip"
- case s: CDefMemory => {
- if (s.seq) s"smem ${s.name} : ${serialize(s.tpe)} [${s.size}]${s.info}"
- else s"cmem ${s.name} : ${serialize(s.tpe)} [${s.size}]${s.info}"
- }
- case s: CDefMPort => {
- val dir = s.direction match {
- case MInfer => "infer"
- case MRead => "read"
- case MWrite => "write"
- case MReadWrite => "rdwr"
- }
- s"${dir} mport ${s.name} = ${s.mem}[${serialize(s.exps(0))}], ${serialize(s.exps(1))}${s.info}"
- }
- }
- }
-
- def serialize(w: Width): String = {
- w match {
- case UnknownWidth => ""
- case w: IntWidth => s"<${w.width.toString}>"
- case w: VarWidth => s"<${w.name}>"
- }
- }
-
- def serialize(f: Orientation): String = {
- f match {
- case Flip => "flip "
- case Default => ""
- }
- }
-
- def serialize(field: Field): String =
- s"${serialize(field.flip)}${field.name} : ${serialize(field.tpe)}"
-
- def serialize(t: Type): String = {
- val commas = ", " // for mkString in BundleType
- t match {
- case ClockType => "Clock"
- case UnknownType => "?"
- case t: UIntType => s"UInt${serialize(t.width)}"
- case t: SIntType => s"SInt${serialize(t.width)}"
- case t: BundleType => s"{ ${t.fields.map(serialize).mkString(commas)}}"
- case t: VectorType => s"${serialize(t.tpe)}[${t.size}]"
- }
- }
-
- def serialize(d: Direction): String = {
- d match {
- case Input => "input"
- case Output => "output"
- }
- }
-
- def serialize(p: Port): String =
- s"${serialize(p.direction)} ${p.name} : ${serialize(p.tpe)}${p.info}"
-
- def serialize(m: DefModule): String = {
- m match {
- case m: Module => {
- var s = new StringBuilder(s"module ${m.name} :${m.info}")
- withIndent {
- s ++= m.ports.map(newline ++ serialize(_)).mkString
- s ++= newline ++ serialize(m.body)
- }
- s.toString
- }
- case m: ExtModule => {
- var s = new StringBuilder(s"extmodule ${m.name} :${m.info}")
- withIndent {
- s ++= m.ports.map(newline ++ serialize(_)).mkString
- s ++= newline
- }
- s.toString
- }
- }
- }
-
- def serialize(c: Circuit): String = {
- var s = new StringBuilder(s"circuit ${c.main} :${c.info}")
- withIndent { s ++= newline ++ c.modules.map(serialize).mkString(newline + newline) }
- s ++= newline ++ newline
- s.toString
- }
-
- private var indentLevel = 0
- private def newline = "\n" + (" " * indentLevel)
- private def indent(): Unit = indentLevel += 1
- private def unindent() { require(indentLevel > 0); indentLevel -= 1 }
- private def withIndent(f: => Unit) { indent(); f; unindent() }
-}
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index 9d11ca2f..383d4df7 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -62,6 +62,12 @@ object Utils extends LazyLogging {
result
}
+ /** Indent the results of [[ir.FirrtlNode.serialize]] */
+ def indent(str: String) = str replaceAllLiterally ("\n", "\n ")
+ def serialize(bi: BigInt): String =
+ if (bi < BigInt(0)) "\"h" + bi.toString(16).substring(1) + "\""
+ else "\"h" + bi.toString(16) + "\""
+
implicit class WithAs[T](x: T) {
import scala.reflect._
def as[O: ClassTag]: Option[O] = x match {
diff --git a/src/main/scala/firrtl/WIR.scala b/src/main/scala/firrtl/WIR.scala
index f0c56358..4ed639da 100644
--- a/src/main/scala/firrtl/WIR.scala
+++ b/src/main/scala/firrtl/WIR.scala
@@ -29,7 +29,6 @@ package firrtl
import scala.collection.Seq
import Utils._
-import firrtl.Serialize._
import firrtl.ir._
import WrappedExpression._
import WrappedWidth._
@@ -41,7 +40,7 @@ case class RegKind() extends Kind
case class InstanceKind() extends Kind
case class PortKind() extends Kind
case class NodeKind() extends Kind
-case class MemKind(ports:Seq[String]) extends Kind
+case class MemKind(ports: Seq[String]) extends Kind
case class ExpKind() extends Kind
trait Gender
@@ -50,15 +49,34 @@ case object FEMALE extends Gender
case object BIGENDER extends Gender
case object UNKNOWNGENDER extends Gender
-case class WRef(name:String,tpe:Type,kind:Kind,gender:Gender) extends Expression
-case class WSubField(exp:Expression,name:String,tpe:Type,gender:Gender) extends Expression
-case class WSubIndex(exp:Expression,value:Int,tpe:Type,gender:Gender) extends Expression
-case class WSubAccess(exp:Expression,index:Expression,tpe:Type,gender:Gender) extends Expression
-case class WVoid() extends Expression { def tpe = UnknownType }
-case class WInvalid() extends Expression { def tpe = UnknownType }
+case class WRef(name: String, tpe: Type, kind: Kind, gender: Gender) extends Expression {
+ def serialize: String = name
+}
+case class WSubField(exp: Expression, name: String, tpe: Type, gender: Gender) extends Expression {
+ def serialize: String = s"${exp.serialize}.$name"
+}
+case class WSubIndex(exp: Expression, value: Int, tpe: Type, gender: Gender) extends Expression {
+ def serialize: String = s"${exp.serialize}[$value]"
+}
+case class WSubAccess(exp: Expression, index: Expression, tpe: Type, gender: Gender) extends Expression {
+ def serialize: String = s"${exp.serialize}[${index.serialize}]"
+}
+case class WVoid() extends Expression {
+ def tpe = UnknownType
+ def serialize: String = "VOID"
+}
+case class WInvalid() extends Expression {
+ def tpe = UnknownType
+ def serialize: String = "INVALID"
+}
// Useful for splitting then remerging references
-case object EmptyExpression extends Expression { def tpe = UnknownType }
-case class WDefInstance(info:Info,name:String,module:String,tpe:Type) extends Statement with IsDeclaration
+case object EmptyExpression extends Expression {
+ def tpe = UnknownType
+ def serialize: String = "EMPTY"
+}
+case class WDefInstance(info: Info, name: String, module: String, tpe: Type) extends Statement with IsDeclaration {
+ def serialize: String = s"inst $name of $module" + info.serialize
+}
// Resultant width is the same as the maximum input width
case object Addw extends PrimOp { override def toString = "addw" }
@@ -106,12 +124,24 @@ class WrappedExpression (val e1:Expression) {
}
-case class VarWidth(name:String) extends Width
-case class PlusWidth(arg1:Width,arg2:Width) extends Width
-case class MinusWidth(arg1:Width,arg2:Width) extends Width
-case class MaxWidth(args:Seq[Width]) extends Width
-case class MinWidth(args:Seq[Width]) extends Width
-case class ExpWidth(arg1:Width) extends Width
+case class VarWidth(name: String) extends Width {
+ def serialize: String = name
+}
+case class PlusWidth(arg1: Width, arg2: Width) extends Width {
+ def serialize: String = "(" + arg1.serialize + " + " + arg2.serialize + ")"
+}
+case class MinusWidth(arg1: Width, arg2: Width) extends Width {
+ def serialize: String = "(" + arg1.serialize + " - " + arg2.serialize + ")"
+}
+case class MaxWidth(args: Seq[Width]) extends Width {
+ def serialize: String = args map (_.serialize) mkString ("max(", ", ", ")")
+}
+case class MinWidth(args: Seq[Width]) extends Width {
+ def serialize: String = args map (_.serialize) mkString ("min(", ", ", ")")
+}
+case class ExpWidth(arg1: Width) extends Width {
+ def serialize: String = "exp(" + arg1.serialize + " )"
+}
object WrappedType {
def apply (t:Type) = new WrappedType(t)
@@ -221,12 +251,38 @@ object WGeq {
def apply (loc:Width,exp:Width) = new WGeq(loc,exp)
}
-trait MPortDir
-case object MInfer extends MPortDir
-case object MRead extends MPortDir
-case object MWrite extends MPortDir
-case object MReadWrite extends MPortDir
+abstract class MPortDir extends FirrtlNode
+case object MInfer extends MPortDir {
+ def serialize: String = "infer"
+}
+case object MRead extends MPortDir {
+ def serialize: String = "read"
+}
+case object MWrite extends MPortDir {
+ def serialize: String = "write"
+}
+case object MReadWrite extends MPortDir {
+ def serialize: String = "rdwr"
+}
-case class CDefMemory (val info: Info, val name: String, val tpe: Type, val size: Int, val seq: Boolean) extends Statement
-case class CDefMPort (val info: Info, val name: String, val tpe: Type, val mem: String, val exps: Seq[Expression], val direction: MPortDir) extends Statement
+case class CDefMemory(
+ info: Info,
+ name: String,
+ tpe: Type,
+ size: Int,
+ seq: Boolean) extends Statement {
+ def serialize: String = (if (seq) "smem" else "cmem") +
+ s" $name : ${tpe.serialize} [$size]" + info.serialize
+}
+case class CDefMPort(info: Info,
+ name: String,
+ tpe: Type,
+ mem: String,
+ exps: Seq[Expression],
+ direction: MPortDir) extends Statement {
+ def serialize: String = {
+ val dir = direction.serialize
+ s"$dir mport $name = $mem[${exps(0).serialize}], ${exps(1).serialize}" + info.serialize
+ }
+}
diff --git a/src/main/scala/firrtl/ir/IR.scala b/src/main/scala/firrtl/ir/IR.scala
index fc5e26b8..76c7c91e 100644
--- a/src/main/scala/firrtl/ir/IR.scala
+++ b/src/main/scala/firrtl/ir/IR.scala
@@ -28,17 +28,22 @@ MODIFICATIONS.
package firrtl
package ir
-trait Info
-case object NoInfo extends Info {
- override def toString(): String = ""
-}
-case class FileInfo(info: StringLit) extends Info {
- override def toString(): String = " @[" + info.serialize + "]"
-}
+import Utils.indent
/** Intermediate Representation */
abstract class FirrtlNode {
- def serialize: String = firrtl.Serialize.serialize(this)
+ def serialize: String
+}
+
+abstract class Info extends FirrtlNode {
+ // default implementation
+ def serialize: String = this.toString
+}
+case object NoInfo extends Info {
+ override def toString: String = ""
+}
+case class FileInfo(info: StringLit) extends Info {
+ override def toString: String = " @[" + info.serialize + "]"
}
trait HasName {
@@ -49,45 +54,75 @@ trait HasInfo {
}
trait IsDeclaration extends HasName with HasInfo
-case class StringLit(array: Array[Byte]) extends FirrtlNode
+case class StringLit(array: Array[Byte]) extends FirrtlNode {
+ def serialize: String = FIRRTLStringLitHandler.escape(this)
+}
/** Primitive Operation
*
* See [[PrimOps]]
*/
-abstract class PrimOp extends FirrtlNode
+abstract class PrimOp extends FirrtlNode {
+ def serialize: String = this.toString
+}
abstract class Expression extends FirrtlNode {
def tpe: Type
}
-case class Reference(name: String, tpe: Type) extends Expression with HasName
-case class SubField(expr: Expression, name: String, tpe: Type) extends Expression with HasName
-case class SubIndex(expr: Expression, value: Int, tpe: Type) extends Expression
-case class SubAccess(expr: Expression, index: Expression, tpe: Type) extends Expression
-case class Mux(cond: Expression, tval: Expression, fval: Expression, tpe: Type) extends Expression
-case class ValidIf(cond: Expression, value: Expression, tpe: Type) extends Expression
+case class Reference(name: String, tpe: Type) extends Expression with HasName {
+ def serialize: String = name
+}
+case class SubField(expr: Expression, name: String, tpe: Type) extends Expression with HasName {
+ def serialize: String = s"${expr.serialize}.$name"
+}
+case class SubIndex(expr: Expression, value: Int, tpe: Type) extends Expression {
+ def serialize: String = s"${expr.serialize}[$value]"
+}
+case class SubAccess(expr: Expression, index: Expression, tpe: Type) extends Expression {
+ def serialize: String = s"${expr.serialize}[${index.serialize}]"
+}
+case class Mux(cond: Expression, tval: Expression, fval: Expression, tpe: Type) extends Expression {
+ def serialize: String = s"mux(${cond.serialize}, ${tval.serialize}, ${fval.serialize})"
+}
+case class ValidIf(cond: Expression, value: Expression, tpe: Type) extends Expression {
+ def serialize: String = s"validif(${cond.serialize}, ${value.serialize})"
+}
abstract class Literal extends Expression {
val value: BigInt
val width: Width
}
case class UIntLiteral(value: BigInt, width: Width) extends Literal {
def tpe = UIntType(width)
+ def serialize = s"UInt${width.serialize}(" + Utils.serialize(value) + ")"
}
case class SIntLiteral(value: BigInt, width: Width) extends Literal {
def tpe = SIntType(width)
+ def serialize = s"SInt${width.serialize}(" + Utils.serialize(value) + ")"
+}
+case class DoPrim(op: PrimOp, args: Seq[Expression], consts: Seq[BigInt], tpe: Type) extends Expression {
+ def serialize: String = op.serialize + "(" +
+ (args.map(_.serialize) ++ consts.map(_.toString)).mkString(", ") + ")"
}
-case class DoPrim(op: PrimOp, args: Seq[Expression], consts: Seq[BigInt], tpe: Type) extends Expression
abstract class Statement extends FirrtlNode
-case class DefWire(info: Info, name: String, tpe: Type) extends Statement with IsDeclaration
+case class DefWire(info: Info, name: String, tpe: Type) extends Statement with IsDeclaration {
+ def serialize: String = s"wire $name : ${tpe.serialize}" + info.serialize
+}
case class DefRegister(
info: Info,
name: String,
tpe: Type,
clock: Expression,
reset: Expression,
- init: Expression) extends Statement with IsDeclaration
-case class DefInstance(info: Info, name: String, module: String) extends Statement with IsDeclaration
+ init: Expression) extends Statement with IsDeclaration {
+ def serialize: String =
+ s"reg $name : ${tpe.serialize}, ${clock.serialize} with :" +
+ indent("\n" + s"reset => (${reset.serialize}, ${init.serialize})" + info.serialize)
+
+}
+case class DefInstance(info: Info, name: String, module: String) extends Statement with IsDeclaration {
+ def serialize: String = s"inst $name of $module" + info.serialize
+}
case class DefMemory(
info: Info,
name: String,
@@ -99,25 +134,63 @@ case class DefMemory(
writers: Seq[String],
readwriters: Seq[String],
// TODO: handle read-under-write
- readUnderWrite: Option[String] = None) extends Statement with IsDeclaration
-case class DefNode(info: Info, name: String, value: Expression) extends Statement with IsDeclaration
+ readUnderWrite: Option[String] = None) extends Statement with IsDeclaration {
+ def serialize: String =
+ s"mem $name :" + info.serialize +
+ indent(
+ Seq("\ndata-type => " + dataType.serialize,
+ "depth => " + depth,
+ "read-latency => " + readLatency,
+ "write-latency => " + writeLatency,
+ readers map ("reader => " + _),
+ writers map ("writer => " + _),
+ readwriters map ("readwriter" + _),
+ "read-under-write => undefined") mkString "\n")
+}
+case class DefNode(info: Info, name: String, value: Expression) extends Statement with IsDeclaration {
+ def serialize: String = s"node $name = ${value.serialize}" + info.serialize
+}
case class Conditionally(
info: Info,
pred: Expression,
conseq: Statement,
- alt: Statement) extends Statement with HasInfo
-case class Block(stmts: Seq[Statement]) extends Statement
-case class PartialConnect(info: Info, loc: Expression, expr: Expression) extends Statement with HasInfo
-case class Connect(info: Info, loc: Expression, expr: Expression) extends Statement with HasInfo
-case class IsInvalid(info: Info, expr: Expression) extends Statement with HasInfo
-case class Stop(info: Info, ret: Int, clk: Expression, en: Expression) extends Statement with HasInfo
+ alt: Statement) extends Statement with HasInfo {
+ def serialize: String =
+ s"when ${pred.serialize} :" + info.serialize +
+ indent("\n" + conseq.serialize) +
+ (if (alt == EmptyStmt) ""
+ else "\nelse :" + indent("\n" + alt.serialize))
+}
+case class Block(stmts: Seq[Statement]) extends Statement {
+ def serialize: String = stmts map (_.serialize) mkString "\n"
+}
+case class PartialConnect(info: Info, loc: Expression, expr: Expression) extends Statement with HasInfo {
+ def serialize: String = s"${loc.serialize} <- ${expr.serialize}" + info.serialize
+}
+case class Connect(info: Info, loc: Expression, expr: Expression) extends Statement with HasInfo {
+ def serialize: String = s"${loc.serialize} <= ${expr.serialize}" + info.serialize
+}
+case class IsInvalid(info: Info, expr: Expression) extends Statement with HasInfo {
+ def serialize: String = s"${expr.serialize} is invalid" + info.serialize
+}
+case class Stop(info: Info, ret: Int, clk: Expression, en: Expression) extends Statement with HasInfo {
+ def serialize: String = s"stop(${clk.serialize}, ${en.serialize}, $ret)" + info.serialize
+}
case class Print(
info: Info,
string: StringLit,
args: Seq[Expression],
clk: Expression,
- en: Expression) extends Statement with HasInfo
-case object EmptyStmt extends Statement
+ en: Expression) extends Statement with HasInfo {
+ def serialize: String = {
+ val strs = Seq(clk.serialize, en.serialize, ("\"" + string.serialize + "\"")) ++
+ (args map (_.serialize))
+ "printf(" + (strs mkString ", ") + ")" + info.serialize
+ }
+}
+case object EmptyStmt extends Statement {
+ def serialize: String = "skip"
+}
abstract class Width extends FirrtlNode {
def +(x: Width): Width = (this, x) match {
@@ -138,54 +211,96 @@ abstract class Width extends FirrtlNode {
}
}
/** Positive Integer Bit Width of a [[GroundType]] */
-case class IntWidth(width: BigInt) extends Width
-case object UnknownWidth extends Width
+case class IntWidth(width: BigInt) extends Width {
+ def serialize: String = s"<$width>"
+}
+case object UnknownWidth extends Width {
+ def serialize: String = ""
+}
/** Orientation of [[Field]] */
abstract class Orientation extends FirrtlNode
-case object Default extends Orientation
-case object Flip extends Orientation
+case object Default extends Orientation {
+ def serialize: String = ""
+}
+case object Flip extends Orientation {
+ def serialize: String = "flip "
+}
/** Field of [[BundleType]] */
-case class Field(name: String, flip: Orientation, tpe: Type) extends FirrtlNode with HasName
+case class Field(name: String, flip: Orientation, tpe: Type) extends FirrtlNode with HasName {
+ def serialize: String = flip.serialize + name + " : " + tpe.serialize
+}
abstract class Type extends FirrtlNode
abstract class GroundType extends Type {
val width: Width
}
abstract class AggregateType extends Type
-case class UIntType(width: Width) extends GroundType
-case class SIntType(width: Width) extends GroundType
-case class BundleType(fields: Seq[Field]) extends AggregateType
-case class VectorType(tpe: Type, size: Int) extends AggregateType
+case class UIntType(width: Width) extends GroundType {
+ def serialize: String = "UInt" + width.serialize
+}
+case class SIntType(width: Width) extends GroundType {
+ def serialize: String = "SInt" + width.serialize
+}
+case class BundleType(fields: Seq[Field]) extends AggregateType {
+ def serialize: String = "{ " + (fields map (_.serialize) mkString ", ") + "}"
+}
+case class VectorType(tpe: Type, size: Int) extends AggregateType {
+ def serialize: String = tpe.serialize + s"[$size]"
+}
case object ClockType extends GroundType {
val width = IntWidth(1)
+ def serialize: String = "Clock"
+}
+case object UnknownType extends Type {
+ def serialize: String = "?"
}
-case object UnknownType extends Type
/** [[Port]] Direction */
abstract class Direction extends FirrtlNode
-case object Input extends Direction
-case object Output extends Direction
+case object Input extends Direction {
+ def serialize: String = "input"
+}
+case object Output extends Direction {
+ def serialize: String = "output"
+}
/** [[DefModule]] Port */
-case class Port(info: Info, name: String, direction: Direction, tpe: Type) extends FirrtlNode with IsDeclaration
+case class Port(
+ info: Info,
+ name: String,
+ direction: Direction,
+ tpe: Type) extends FirrtlNode with IsDeclaration {
+ def serialize: String = s"${direction.serialize} $name : ${tpe.serialize}" + info.serialize
+}
/** Base class for modules */
abstract class DefModule extends FirrtlNode with IsDeclaration {
val info : Info
val name : String
val ports : Seq[Port]
+ protected def serializeHeader(tpe: String): String =
+ s"$tpe $name :" + info.serialize +
+ indent(ports map ("\n" + _.serialize) mkString) + "\n"
}
/** Internal Module
*
* An instantiable hardware block
*/
-case class Module(info: Info, name: String, ports: Seq[Port], body: Statement) extends DefModule
+case class Module(info: Info, name: String, ports: Seq[Port], body: Statement) extends DefModule {
+ def serialize: String = serializeHeader("module") + indent("\n" + body.serialize)
+}
/** External Module
*
* Generally used for Verilog black boxes
*/
-case class ExtModule(info: Info, name: String, ports: Seq[Port]) extends DefModule
+case class ExtModule(info: Info, name: String, ports: Seq[Port]) extends DefModule {
+ def serialize: String = serializeHeader("extmodule")
+}
-case class Circuit(info: Info, modules: Seq[DefModule], main: String) extends FirrtlNode with HasInfo
+case class Circuit(info: Info, modules: Seq[DefModule], main: String) extends FirrtlNode with HasInfo {
+ def serialize: String =
+ s"circuit $main :" + info.serialize +
+ (modules map ("\n" + _.serialize) map indent mkString "\n") + "\n"
+}
diff --git a/src/main/scala/firrtl/passes/CheckChirrtl.scala b/src/main/scala/firrtl/passes/CheckChirrtl.scala
index 42f5bba2..60a49bac 100644
--- a/src/main/scala/firrtl/passes/CheckChirrtl.scala
+++ b/src/main/scala/firrtl/passes/CheckChirrtl.scala
@@ -37,7 +37,6 @@ import firrtl._
import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
-import firrtl.Serialize._
import firrtl.PrimOps._
import firrtl.WrappedType._
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala
index ab6db202..7350a8c1 100644
--- a/src/main/scala/firrtl/passes/Checks.scala
+++ b/src/main/scala/firrtl/passes/Checks.scala
@@ -37,7 +37,6 @@ import firrtl._
import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
-import firrtl.Serialize._
import firrtl.PrimOps._
import firrtl.WrappedType._
@@ -689,7 +688,7 @@ object CheckWidths extends Pass {
class UninferredWidth (info:Info) extends PassException(s"${info} : [module ${mname}] Uninferred width.")
class WidthTooSmall(info: Info, b: BigInt) extends PassException(
s"$info : [module $mname] Width too small for constant " +
- Serialize().serialize(b) + ".")
+ serialize(b) + ".")
class NegWidthException(info:Info) extends PassException(s"${info}: [module ${mname}] Width cannot be negative or zero.")
def run (c:Circuit): Circuit = {
val errors = new Errors()
diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala
index bd9563dc..135d00b3 100644
--- a/src/main/scala/firrtl/passes/Passes.scala
+++ b/src/main/scala/firrtl/passes/Passes.scala
@@ -39,7 +39,6 @@ import firrtl._
import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
-import firrtl.Serialize._
import firrtl.PrimOps._
import firrtl.WrappedExpression._