diff options
| -rw-r--r-- | src/main/scala/firrtl/Emitter.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Serialize.scala | 238 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/firrtl/WIR.scala | 102 | ||||
| -rw-r--r-- | src/main/scala/firrtl/ir/IR.scala | 207 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/CheckChirrtl.scala | 1 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/Checks.scala | 3 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/Passes.scala | 1 |
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._ |
