aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/ir
diff options
context:
space:
mode:
authorchick2020-08-14 19:47:53 -0700
committerJack Koenig2020-08-14 19:47:53 -0700
commit6fc742bfaf5ee508a34189400a1a7dbffe3f1cac (patch)
tree2ed103ee80b0fba613c88a66af854ae9952610ce /src/main/scala/firrtl/ir
parentb516293f703c4de86397862fee1897aded2ae140 (diff)
All of src/ formatted with scalafmt
Diffstat (limited to 'src/main/scala/firrtl/ir')
-rw-r--r--src/main/scala/firrtl/ir/IR.scala869
-rw-r--r--src/main/scala/firrtl/ir/Serializer.scala247
-rw-r--r--src/main/scala/firrtl/ir/StructuralHash.scala291
3 files changed, 762 insertions, 645 deletions
diff --git a/src/main/scala/firrtl/ir/IR.scala b/src/main/scala/firrtl/ir/IR.scala
index 5263d9c0..2536a77e 100644
--- a/src/main/scala/firrtl/ir/IR.scala
+++ b/src/main/scala/firrtl/ir/IR.scala
@@ -39,41 +39,50 @@ case class FileInfo(escaped: String) extends Info {
object FileInfo {
@deprecated("Use FileInfo.fromUnEscaped instead. FileInfo.apply will be removed in FIRRTL 1.5.", "FIRRTL 1.4")
- def apply(info: StringLit): FileInfo = new FileInfo(escape(info.string))
- def fromEscaped(s: String): FileInfo = new FileInfo(s)
- def fromUnescaped(s: String): FileInfo = new FileInfo(escape(s))
+ def apply(info: StringLit): FileInfo = new FileInfo(escape(info.string))
+ def fromEscaped(s: String): FileInfo = new FileInfo(s)
+ def fromUnescaped(s: String): FileInfo = new FileInfo(escape(s))
+
/** prepends a `\` to: `\`, `\n`, `\t` and `]` */
def escape(s: String): String = EscapeFirrtl.translate(s)
+
/** removes the `\` in front of `\`, `\n`, `\t` and `]` */
def unescape(s: String): String = UnescapeFirrtl.translate(s)
+
/** take an already escaped String and do the additional escaping needed for Verilog comment */
def escapedToVerilog(s: String) = EscapedToVerilog.translate(s)
// custom `CharSequenceTranslator` for FIRRTL Info String escaping
type CharMap = (CharSequence, CharSequence)
- private val EscapeFirrtl = new LookupTranslator(Seq[CharMap](
- "\\" -> "\\\\",
- "\n" -> "\\n",
- "\t" -> "\\t",
- "]" -> "\\]"
- ).toMap.asJava)
- private val UnescapeFirrtl = new LookupTranslator(Seq[CharMap](
- "\\\\" -> "\\",
- "\\n" -> "\n",
- "\\t" -> "\t",
- "\\]" -> "]"
- ).toMap.asJava)
+ private val EscapeFirrtl = new LookupTranslator(
+ Seq[CharMap](
+ "\\" -> "\\\\",
+ "\n" -> "\\n",
+ "\t" -> "\\t",
+ "]" -> "\\]"
+ ).toMap.asJava
+ )
+ private val UnescapeFirrtl = new LookupTranslator(
+ Seq[CharMap](
+ "\\\\" -> "\\",
+ "\\n" -> "\n",
+ "\\t" -> "\t",
+ "\\]" -> "]"
+ ).toMap.asJava
+ )
// EscapeFirrtl + EscapedToVerilog essentially does the same thing as running StringEscapeUtils.unescapeJava
private val EscapedToVerilog = new AggregateTranslator(
- new LookupTranslator(Seq[CharMap](
- // ] is the one character that firrtl needs to be escaped that does not need to be escaped in
- "\\]" -> "]",
- "\"" -> "\\\"",
- // \n and \t are already escaped
- "\b" -> "\\b",
- "\f" -> "\\f",
- "\r" -> "\\r"
- ).toMap.asJava),
+ new LookupTranslator(
+ Seq[CharMap](
+ // ] is the one character that firrtl needs to be escaped that does not need to be escaped in
+ "\\]" -> "]",
+ "\"" -> "\\\"",
+ // \n and \t are already escaped
+ "\b" -> "\\b",
+ "\f" -> "\\f",
+ "\r" -> "\\r"
+ ).toMap.asJava
+ ),
JavaUnicodeEscaper.outsideOf(32, 0x7f)
)
@@ -81,9 +90,9 @@ object FileInfo {
case class MultiInfo(infos: Seq[Info]) extends Info {
private def collectStrings(info: Info): Seq[String] = info match {
- case f : FileInfo => Seq(f.escaped)
- case MultiInfo(seq) => seq flatMap collectStrings
- case NoInfo => Seq.empty
+ case f: FileInfo => Seq(f.escaped)
+ case MultiInfo(seq) => seq.flatMap(collectStrings)
+ case NoInfo => Seq.empty
}
override def toString: String = {
val parts = collectStrings(this)
@@ -107,12 +116,12 @@ object MultiInfo {
// TODO should this be made into an API?
private[firrtl] def demux(info: Info): (Info, Info, Info) = info match {
case MultiInfo(infos) if infos.lengthCompare(3) == 0 => (infos(0), infos(1), infos(2))
- case other => (other, NoInfo, NoInfo) // if not exactly 3, we don't know what to do
+ case other => (other, NoInfo, NoInfo) // if not exactly 3, we don't know what to do
}
-
+
private def flattenInfo(infos: Seq[Info]): Seq[FileInfo] = infos.flatMap {
case NoInfo => Seq()
- case f : FileInfo => Seq(f)
+ case f: FileInfo => Seq(f)
case MultiInfo(infos) => flattenInfo(infos)
}
}
@@ -127,6 +136,7 @@ trait IsDeclaration extends HasName with HasInfo
case class StringLit(string: String) extends FirrtlNode {
import org.apache.commons.text.StringEscapeUtils
+
/** Returns an escaped and quoted String */
def escape: String = {
"\"" + serialize + "\""
@@ -137,26 +147,28 @@ case class StringLit(string: String) extends FirrtlNode {
def verilogFormat: StringLit = {
StringLit(string.replaceAll("%x", "%h"))
}
+
/** Returns an escaped and quoted String */
def verilogEscape: String = {
// normalize to turn things like รถ into o
import java.text.Normalizer
val normalized = Normalizer.normalize(string, Normalizer.Form.NFD)
- val ascii = normalized flatMap StringLit.toASCII
+ val ascii = normalized.flatMap(StringLit.toASCII)
ascii.mkString("\"", "", "\"")
}
}
object StringLit {
import org.apache.commons.text.StringEscapeUtils
+
/** Maps characters to ASCII for Verilog emission */
private def toASCII(char: Char): List[Char] = char match {
case nonASCII if !nonASCII.isValidByte => List('?')
- case '"' => List('\\', '"')
- case '\\' => List('\\', '\\')
- case c if c >= ' ' && c <= '~' => List(c)
- case '\n' => List('\\', 'n')
- case '\t' => List('\\', 't')
- case _ => List('?')
+ case '"' => List('\\', '"')
+ case '\\' => List('\\', '\\')
+ case c if c >= ' ' && c <= '~' => List(c)
+ case '\n' => List('\\', 'n')
+ case '\t' => List('\\', 't')
+ case _ => List('?')
}
/** Create a StringLit from a raw parsed String */
@@ -175,8 +187,8 @@ abstract class PrimOp extends FirrtlNode {
def apply(args: Any*): DoPrim = {
val groups = args.groupBy {
case x: Expression => "exp"
- case x: BigInt => "int"
- case x: Int => "int"
+ case x: BigInt => "int"
+ case x: Int => "int"
case other => "other"
}
val exprs = groups.getOrElse("exp", Nil).collect {
@@ -185,11 +197,11 @@ abstract class PrimOp extends FirrtlNode {
val consts = groups.getOrElse("int", Nil).map {
_ match {
case i: BigInt => i
- case i: Int => BigInt(i)
+ case i: Int => BigInt(i)
}
}
groups.get("other") match {
- case None =>
+ case None =>
case Some(x) => sys.error(s"Shouldn't be here: $x")
}
DoPrim(this, exprs, consts, UnknownType)
@@ -198,12 +210,12 @@ abstract class PrimOp extends FirrtlNode {
abstract class Expression extends FirrtlNode {
def tpe: Type
- def mapExpr(f: Expression => Expression): Expression
- def mapType(f: Type => Type): Expression
- def mapWidth(f: Width => Width): Expression
- def foreachExpr(f: Expression => Unit): Unit
- def foreachType(f: Type => Unit): Unit
- def foreachWidth(f: Width => Unit): Unit
+ def mapExpr(f: Expression => Expression): Expression
+ def mapType(f: Type => Type): Expression
+ def mapWidth(f: Width => Width): Expression
+ def foreachExpr(f: Expression => Unit): Unit
+ def foreachType(f: Type => Unit): Unit
+ def foreachWidth(f: Width => Unit): Unit
}
/** Represents reference-like expression nodes: SubField, SubIndex, SubAccess and Reference
@@ -215,75 +227,92 @@ abstract class Expression extends FirrtlNode {
sealed trait RefLikeExpression extends Expression { def flow: Flow }
object Reference {
+
/** Creates a Reference from a Wire */
def apply(wire: DefWire): Reference = Reference(wire.name, wire.tpe, WireKind, UnknownFlow)
+
/** Creates a Reference from a Register */
def apply(reg: DefRegister): Reference = Reference(reg.name, reg.tpe, RegKind, UnknownFlow)
+
/** Creates a Reference from a Node */
def apply(node: DefNode): Reference = Reference(node.name, node.value.tpe, NodeKind, SourceFlow)
+
/** Creates a Reference from a Port */
def apply(port: Port): Reference = Reference(port.name, port.tpe, PortKind, UnknownFlow)
+
/** Creates a Reference from a DefInstance */
def apply(i: DefInstance): Reference = Reference(i.name, i.tpe, InstanceKind, UnknownFlow)
+
/** Creates a Reference from a DefMemory */
def apply(mem: DefMemory): Reference = Reference(mem.name, passes.MemPortUtils.memType(mem), MemKind, UnknownFlow)
}
case class Reference(name: String, tpe: Type = UnknownType, kind: Kind = UnknownKind, flow: Flow = UnknownFlow)
- extends Expression with HasName with UseSerializer with RefLikeExpression {
- def mapExpr(f: Expression => Expression): Expression = this
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = f(tpe)
- def foreachWidth(f: Width => Unit): Unit = ()
+ extends Expression
+ with HasName
+ with UseSerializer
+ with RefLikeExpression {
+ def mapExpr(f: Expression => Expression): Expression = this
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachWidth(f: Width => Unit): Unit = ()
}
case class SubField(expr: Expression, name: String, tpe: Type = UnknownType, flow: Flow = UnknownFlow)
- extends Expression with HasName with UseSerializer with RefLikeExpression {
- def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr))
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
- def foreachExpr(f: Expression => Unit): Unit = f(expr)
- def foreachType(f: Type => Unit): Unit = f(tpe)
- def foreachWidth(f: Width => Unit): Unit = ()
+ extends Expression
+ with HasName
+ with UseSerializer
+ with RefLikeExpression {
+ def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr))
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
+ def foreachExpr(f: Expression => Unit): Unit = f(expr)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachWidth(f: Width => Unit): Unit = ()
}
case class SubIndex(expr: Expression, value: Int, tpe: Type, flow: Flow = UnknownFlow)
- extends Expression with UseSerializer with RefLikeExpression {
- def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr))
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
- def foreachExpr(f: Expression => Unit): Unit = f(expr)
- def foreachType(f: Type => Unit): Unit = f(tpe)
- def foreachWidth(f: Width => Unit): Unit = ()
+ extends Expression
+ with UseSerializer
+ with RefLikeExpression {
+ def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr))
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
+ def foreachExpr(f: Expression => Unit): Unit = f(expr)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachWidth(f: Width => Unit): Unit = ()
}
case class SubAccess(expr: Expression, index: Expression, tpe: Type, flow: Flow = UnknownFlow)
- extends Expression with UseSerializer with RefLikeExpression {
- def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr), index = f(index))
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
+ extends Expression
+ with UseSerializer
+ with RefLikeExpression {
+ def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr), index = f(index))
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = { f(expr); f(index) }
- def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = ()
}
case class Mux(cond: Expression, tval: Expression, fval: Expression, tpe: Type = UnknownType)
- extends Expression with UseSerializer {
- def mapExpr(f: Expression => Expression): Expression = Mux(f(cond), f(tval), f(fval), tpe)
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
+ extends Expression
+ with UseSerializer {
+ def mapExpr(f: Expression => Expression): Expression = Mux(f(cond), f(tval), f(fval), tpe)
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = { f(cond); f(tval); f(fval) }
- def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = ()
}
case class ValidIf(cond: Expression, value: Expression, tpe: Type) extends Expression with UseSerializer {
- def mapExpr(f: Expression => Expression): Expression = ValidIf(f(cond), f(value), tpe)
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
+ def mapExpr(f: Expression => Expression): Expression = ValidIf(f(cond), f(value), tpe)
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = { f(cond); f(value) }
- def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = ()
}
abstract class Literal extends Expression {
@@ -292,16 +321,16 @@ abstract class Literal extends Expression {
}
case class UIntLiteral(value: BigInt, width: Width) extends Literal with UseSerializer {
def tpe = UIntType(width)
- def mapExpr(f: Expression => Expression): Expression = this
- def mapType(f: Type => Type): Expression = this
- def mapWidth(f: Width => Width): Expression = UIntLiteral(value, f(width))
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = ()
- def foreachWidth(f: Width => Unit): Unit = f(width)
+ def mapExpr(f: Expression => Expression): Expression = this
+ def mapType(f: Type => Type): Expression = this
+ def mapWidth(f: Width => Width): Expression = UIntLiteral(value, f(width))
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachWidth(f: Width => Unit): Unit = f(width)
}
object UIntLiteral {
def minWidth(value: BigInt): Width = IntWidth(math.max(value.bitLength, 1))
- def apply(value: BigInt): UIntLiteral = new UIntLiteral(value, minWidth(value))
+ def apply(value: BigInt): UIntLiteral = new UIntLiteral(value, minWidth(value))
/** Utility to construct UIntLiterals masked by the width
*
@@ -314,78 +343,82 @@ object UIntLiteral {
}
case class SIntLiteral(value: BigInt, width: Width) extends Literal with UseSerializer {
def tpe = SIntType(width)
- def mapExpr(f: Expression => Expression): Expression = this
- def mapType(f: Type => Type): Expression = this
- def mapWidth(f: Width => Width): Expression = SIntLiteral(value, f(width))
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = ()
- def foreachWidth(f: Width => Unit): Unit = f(width)
+ def mapExpr(f: Expression => Expression): Expression = this
+ def mapType(f: Type => Type): Expression = this
+ def mapWidth(f: Width => Width): Expression = SIntLiteral(value, f(width))
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachWidth(f: Width => Unit): Unit = f(width)
}
object SIntLiteral {
def minWidth(value: BigInt): Width = IntWidth(value.bitLength + 1)
- def apply(value: BigInt): SIntLiteral = new SIntLiteral(value, minWidth(value))
+ def apply(value: BigInt): SIntLiteral = new SIntLiteral(value, minWidth(value))
}
case class FixedLiteral(value: BigInt, width: Width, point: Width) extends Literal with UseSerializer {
def tpe = FixedType(width, point)
- def mapExpr(f: Expression => Expression): Expression = this
- def mapType(f: Type => Type): Expression = this
- def mapWidth(f: Width => Width): Expression = FixedLiteral(value, f(width), f(point))
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = ()
+ def mapExpr(f: Expression => Expression): Expression = this
+ def mapType(f: Type => Type): Expression = this
+ def mapWidth(f: Width => Width): Expression = FixedLiteral(value, f(width), f(point))
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
def foreachWidth(f: Width => Unit): Unit = { f(width); f(point) }
}
case class DoPrim(op: PrimOp, args: Seq[Expression], consts: Seq[BigInt], tpe: Type)
- extends Expression with UseSerializer {
- def mapExpr(f: Expression => Expression): Expression = this.copy(args = args map f)
- def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
- def mapWidth(f: Width => Width): Expression = this
- def foreachExpr(f: Expression => Unit): Unit = args.foreach(f)
- def foreachType(f: Type => Unit): Unit = f(tpe)
- def foreachWidth(f: Width => Unit): Unit = ()
+ extends Expression
+ with UseSerializer {
+ def mapExpr(f: Expression => Expression): Expression = this.copy(args = args.map(f))
+ def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
+ def mapWidth(f: Width => Width): Expression = this
+ def foreachExpr(f: Expression => Unit): Unit = args.foreach(f)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachWidth(f: Width => Unit): Unit = ()
}
abstract class Statement extends FirrtlNode {
- def mapStmt(f: Statement => Statement): Statement
- def mapExpr(f: Expression => Expression): Statement
- def mapType(f: Type => Type): Statement
- def mapString(f: String => String): Statement
- def mapInfo(f: Info => Info): Statement
- def foreachStmt(f: Statement => Unit): Unit
- def foreachExpr(f: Expression => Unit): Unit
- def foreachType(f: Type => Unit): Unit
- def foreachString(f: String => Unit): Unit
- def foreachInfo(f: Info => Unit): Unit
+ def mapStmt(f: Statement => Statement): Statement
+ def mapExpr(f: Expression => Expression): Statement
+ def mapType(f: Type => Type): Statement
+ def mapString(f: String => String): Statement
+ def mapInfo(f: Info => Info): Statement
+ def foreachStmt(f: Statement => Unit): Unit
+ def foreachExpr(f: Expression => Unit): Unit
+ def foreachType(f: Type => Unit): Unit
+ def foreachString(f: String => Unit): Unit
+ def foreachInfo(f: Info => Unit): Unit
}
case class DefWire(info: Info, name: String, tpe: Type) extends Statement with IsDeclaration with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = this
- def mapType(f: Type => Type): Statement = DefWire(info, name, f(tpe))
- def mapString(f: String => String): Statement = DefWire(info, f(name), tpe)
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = f(tpe)
- def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = this
+ def mapType(f: Type => Type): Statement = DefWire(info, name, f(tpe))
+ def mapString(f: String => String): Statement = DefWire(info, f(name), tpe)
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachString(f: String => Unit): Unit = f(name)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class DefRegister(
- info: Info,
- name: String,
- tpe: Type,
- clock: Expression,
- reset: Expression,
- init: Expression) extends Statement with IsDeclaration with UseSerializer {
+ info: Info,
+ name: String,
+ tpe: Type,
+ clock: Expression,
+ reset: Expression,
+ init: Expression)
+ extends Statement
+ with IsDeclaration
+ with UseSerializer {
def mapStmt(f: Statement => Statement): Statement = this
def mapExpr(f: Expression => Expression): Statement =
DefRegister(info, name, tpe, f(clock), f(reset), f(init))
- def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
- def mapString(f: String => String): Statement = this.copy(name = f(name))
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
+ def mapString(f: String => String): Statement = this.copy(name = f(name))
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
def foreachStmt(f: Statement => Unit): Unit = ()
def foreachExpr(f: Expression => Unit): Unit = { f(clock); f(reset); f(init) }
- def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
object DefInstance {
@@ -393,17 +426,19 @@ object DefInstance {
}
case class DefInstance(info: Info, name: String, module: String, tpe: Type = UnknownType)
- extends Statement with IsDeclaration with UseSerializer {
- def mapExpr(f: Expression => Expression): Statement = this
- def mapStmt(f: Statement => Statement): Statement = this
- def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
- def mapString(f: String => String): Statement = this.copy(name = f(name))
- def mapInfo(f: Info => Info): Statement = this.copy(f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = f(tpe)
- def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ extends Statement
+ with IsDeclaration
+ with UseSerializer {
+ def mapExpr(f: Expression => Expression): Statement = this
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
+ def mapString(f: String => String): Statement = this.copy(name = f(name))
+ def mapInfo(f: Info => Info): Statement = this.copy(f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = f(tpe)
+ def foreachString(f: String => Unit): Unit = f(name)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
object ReadUnderWrite extends Enumeration {
@@ -413,56 +448,64 @@ object ReadUnderWrite extends Enumeration {
}
case class DefMemory(
- info: Info,
- name: String,
- dataType: Type,
- depth: BigInt,
- writeLatency: Int,
- readLatency: Int,
- readers: Seq[String],
- writers: Seq[String],
- readwriters: Seq[String],
- // TODO: handle read-under-write
- readUnderWrite: ReadUnderWrite.Value = ReadUnderWrite.Undefined)
- extends Statement with IsDeclaration with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = this
- def mapType(f: Type => Type): Statement = this.copy(dataType = f(dataType))
- def mapString(f: String => String): Statement = this.copy(name = f(name))
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = f(dataType)
- def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
-}
-case class DefNode(info: Info, name: String, value: Expression) extends Statement with IsDeclaration with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = DefNode(info, name, f(value))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = DefNode(info, f(name), value)
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = f(value)
- def foreachType(f: Type => Unit): Unit = ()
- def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ info: Info,
+ name: String,
+ dataType: Type,
+ depth: BigInt,
+ writeLatency: Int,
+ readLatency: Int,
+ readers: Seq[String],
+ writers: Seq[String],
+ readwriters: Seq[String],
+ // TODO: handle read-under-write
+ readUnderWrite: ReadUnderWrite.Value = ReadUnderWrite.Undefined)
+ extends Statement
+ with IsDeclaration
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = this
+ def mapType(f: Type => Type): Statement = this.copy(dataType = f(dataType))
+ def mapString(f: String => String): Statement = this.copy(name = f(name))
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = f(dataType)
+ def foreachString(f: String => Unit): Unit = f(name)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
+}
+case class DefNode(info: Info, name: String, value: Expression)
+ extends Statement
+ with IsDeclaration
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = DefNode(info, name, f(value))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = DefNode(info, f(name), value)
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = f(value)
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachString(f: String => Unit): Unit = f(name)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class Conditionally(
- info: Info,
- pred: Expression,
- conseq: Statement,
- alt: Statement) extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = Conditionally(info, pred, f(conseq), f(alt))
- def mapExpr(f: Expression => Expression): Statement = Conditionally(info, f(pred), conseq, alt)
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ info: Info,
+ pred: Expression,
+ conseq: Statement,
+ alt: Statement)
+ extends Statement
+ with HasInfo
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = Conditionally(info, pred, f(conseq), f(alt))
+ def mapExpr(f: Expression => Expression): Statement = Conditionally(info, f(pred), conseq, alt)
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
def foreachStmt(f: Statement => Unit): Unit = { f(conseq); f(alt) }
- def foreachExpr(f: Expression => Unit): Unit = f(pred)
- def foreachType(f: Type => Unit): Unit = ()
- def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def foreachExpr(f: Expression => Unit): Unit = f(pred)
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachString(f: String => Unit): Unit = ()
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
object Block {
@@ -489,94 +532,101 @@ case class Block(stmts: Seq[Statement]) extends Statement with UseSerializer {
}
Block(res.toSeq)
}
- def mapExpr(f: Expression => Expression): Statement = this
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this
- def foreachStmt(f: Statement => Unit): Unit = stmts.foreach(f)
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = ()
- def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = ()
+ def mapExpr(f: Expression => Expression): Statement = this
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this
+ def foreachStmt(f: Statement => Unit): Unit = stmts.foreach(f)
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachString(f: String => Unit): Unit = ()
+ def foreachInfo(f: Info => Unit): Unit = ()
}
case class PartialConnect(info: Info, loc: Expression, expr: Expression)
- extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = PartialConnect(info, f(loc), f(expr))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
+ extends Statement
+ with HasInfo
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = PartialConnect(info, f(loc), f(expr))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
def foreachExpr(f: Expression => Unit): Unit = { f(loc); f(expr) }
- def foreachType(f: Type => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
-}
-case class Connect(info: Info, loc: Expression, expr: Expression)
- extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = Connect(info, f(loc), f(expr))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachInfo(f: Info => Unit): Unit = f(info)
+}
+case class Connect(info: Info, loc: Expression, expr: Expression) extends Statement with HasInfo with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = Connect(info, f(loc), f(expr))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
def foreachExpr(f: Expression => Unit): Unit = { f(loc); f(expr) }
- def foreachType(f: Type => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class IsInvalid(info: Info, expr: Expression) extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = IsInvalid(info, f(expr))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = f(expr)
- def foreachType(f: Type => Unit): Unit = ()
- def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = IsInvalid(info, f(expr))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = f(expr)
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachString(f: String => Unit): Unit = ()
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class Attach(info: Info, exprs: Seq[Expression]) extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = Attach(info, exprs map f)
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = exprs.foreach(f)
- def foreachType(f: Type => Unit): Unit = ()
- def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
-}
-case class Stop(info: Info, ret: Int, clk: Expression, en: Expression) extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = Stop(info, ret, f(clk), f(en))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = Attach(info, exprs.map(f))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = exprs.foreach(f)
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachString(f: String => Unit): Unit = ()
+ def foreachInfo(f: Info => Unit): Unit = f(info)
+}
+case class Stop(info: Info, ret: Int, clk: Expression, en: Expression)
+ extends Statement
+ with HasInfo
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = Stop(info, ret, f(clk), f(en))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
def foreachExpr(f: Expression => Unit): Unit = { f(clk); f(en) }
- def foreachType(f: Type => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class Print(
- info: Info,
- string: StringLit,
- args: Seq[Expression],
- clk: Expression,
- en: Expression) extends Statement with HasInfo with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = Print(info, string, args map f, f(clk), f(en))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
+ info: Info,
+ string: StringLit,
+ args: Seq[Expression],
+ clk: Expression,
+ en: Expression)
+ extends Statement
+ with HasInfo
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = Print(info, string, args.map(f), f(clk), f(en))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this.copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
def foreachExpr(f: Expression => Unit): Unit = { args.foreach(f); f(clk); f(en) }
- def foreachType(f: Type => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
// formal
@@ -587,38 +637,40 @@ object Formal extends Enumeration {
}
case class Verification(
- op: Formal.Value,
+ op: Formal.Value,
info: Info,
- clk: Expression,
+ clk: Expression,
pred: Expression,
- en: Expression,
- msg: StringLit
-) extends Statement with HasInfo with UseSerializer {
+ en: Expression,
+ msg: StringLit)
+ extends Statement
+ with HasInfo
+ with UseSerializer {
def mapStmt(f: Statement => Statement): Statement = this
def mapExpr(f: Expression => Expression): Statement =
copy(clk = f(clk), pred = f(pred), en = f(en))
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = copy(info = f(info))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = copy(info = f(info))
def foreachStmt(f: Statement => Unit): Unit = ()
def foreachExpr(f: Expression => Unit): Unit = { f(clk); f(pred); f(en); }
- def foreachType(f: Type => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
// end formal
case object EmptyStmt extends Statement with UseSerializer {
- def mapStmt(f: Statement => Statement): Statement = this
- def mapExpr(f: Expression => Expression): Statement = this
- def mapType(f: Type => Type): Statement = this
- def mapString(f: String => String): Statement = this
- def mapInfo(f: Info => Info): Statement = this
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachExpr(f: Expression => Unit): Unit = ()
- def foreachType(f: Type => Unit): Unit = ()
- def foreachString(f: String => Unit): Unit = ()
- def foreachInfo(f: Info => Unit): Unit = ()
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement = this
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = this
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachExpr(f: Expression => Unit): Unit = ()
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachString(f: String => Unit): Unit = ()
+ def foreachInfo(f: Info => Unit): Unit = ()
}
abstract class Width extends FirrtlNode {
@@ -631,14 +683,15 @@ abstract class Width extends FirrtlNode {
case _ => UnknownWidth
}
def max(x: Width): Width = (this, x) match {
- case (a: IntWidth, b: IntWidth) => IntWidth(a.width max b.width)
+ case (a: IntWidth, b: IntWidth) => IntWidth(a.width.max(b.width))
case _ => UnknownWidth
}
def min(x: Width): Width = (this, x) match {
- case (a: IntWidth, b: IntWidth) => IntWidth(a.width min b.width)
+ case (a: IntWidth, b: IntWidth) => IntWidth(a.width.min(b.width))
case _ => UnknownWidth
}
}
+
/** Positive Integer Bit Width of a [[GroundType]] */
object IntWidth {
private val maxCached = 1024
@@ -665,7 +718,7 @@ class IntWidth(val width: BigInt) extends Width with Product with UseSerializer
override def hashCode = width.toInt
override def productPrefix = "IntWidth"
override def toString = s"$productPrefix($width)"
- def copy(width: BigInt = width) = IntWidth(width)
+ def copy(width: BigInt = width) = IntWidth(width)
def canEqual(that: Any) = that.isInstanceOf[Width]
def productArity = 1
def productElement(int: Int) = int match {
@@ -693,19 +746,18 @@ case object Flip extends Orientation {
/** Field of [[BundleType]] */
case class Field(name: String, flip: Orientation, tpe: Type) extends FirrtlNode with HasName with UseSerializer
-
/** Bounds of [[IntervalType]] */
trait Bound extends Constraint
case object UnknownBound extends Bound {
def serialize: String = Serializer.serialize(this)
- def map(f: Constraint=>Constraint): Constraint = this
+ def map(f: Constraint => Constraint): Constraint = this
override def reduce(): Constraint = this
val children = Vector()
}
case class CalcBound(arg: Constraint) extends Bound {
def serialize: String = Serializer.serialize(this)
- def map(f: Constraint=>Constraint): Constraint = f(arg)
+ def map(f: Constraint => Constraint): Constraint = f(arg)
override def reduce(): Constraint = arg
val children = Vector(arg)
}
@@ -727,58 +779,60 @@ case class Open(value: BigDecimal) extends IsKnown with Bound {
def +(that: IsKnown): IsKnown = Open(value + that.value)
def *(that: IsKnown): IsKnown = that match {
case Closed(x) if x == 0 => Closed(x)
- case _ => Open(value * that.value)
+ case _ => Open(value * that.value)
}
- def min(that: IsKnown): IsKnown = if(value < that.value) this else that
- def max(that: IsKnown): IsKnown = if(value > that.value) this else that
- def neg: IsKnown = Open(-value)
- def floor: IsKnown = Open(value.setScale(0, BigDecimal.RoundingMode.FLOOR))
- def pow: IsKnown = if(value.isBinaryDouble) Open(BigDecimal(BigInt(1) << value.toInt)) else sys.error("Shouldn't be here")
+ def min(that: IsKnown): IsKnown = if (value < that.value) this else that
+ def max(that: IsKnown): IsKnown = if (value > that.value) this else that
+ def neg: IsKnown = Open(-value)
+ def floor: IsKnown = Open(value.setScale(0, BigDecimal.RoundingMode.FLOOR))
+ def pow: IsKnown =
+ if (value.isBinaryDouble) Open(BigDecimal(BigInt(1) << value.toInt)) else sys.error("Shouldn't be here")
}
case class Closed(value: BigDecimal) extends IsKnown with Bound {
def serialize: String = Serializer.serialize(this)
def +(that: IsKnown): IsKnown = that match {
- case Open(x) => Open(value + x)
+ case Open(x) => Open(value + x)
case Closed(x) => Closed(value + x)
}
def *(that: IsKnown): IsKnown = that match {
case IsKnown(x) if value == BigInt(0) => Closed(0)
- case Open(x) => Open(value * x)
- case Closed(x) => Closed(value * x)
+ case Open(x) => Open(value * x)
+ case Closed(x) => Closed(value * x)
}
- def min(that: IsKnown): IsKnown = if(value <= that.value) this else that
- def max(that: IsKnown): IsKnown = if(value >= that.value) this else that
- def neg: IsKnown = Closed(-value)
+ def min(that: IsKnown): IsKnown = if (value <= that.value) this else that
+ def max(that: IsKnown): IsKnown = if (value >= that.value) this else that
+ def neg: IsKnown = Closed(-value)
def floor: IsKnown = Closed(value.setScale(0, BigDecimal.RoundingMode.FLOOR))
- def pow: IsKnown = if(value.isBinaryDouble) Closed(BigDecimal(BigInt(1) << value.toInt)) else sys.error("Shouldn't be here")
+ def pow: IsKnown =
+ if (value.isBinaryDouble) Closed(BigDecimal(BigInt(1) << value.toInt)) else sys.error("Shouldn't be here")
}
/** Types of [[FirrtlNode]] */
abstract class Type extends FirrtlNode {
- def mapType(f: Type => Type): Type
- def mapWidth(f: Width => Width): Type
- def foreachType(f: Type => Unit): Unit
- def foreachWidth(f: Width => Unit): Unit
+ def mapType(f: Type => Type): Type
+ def mapWidth(f: Width => Width): Type
+ def foreachType(f: Type => Unit): Unit
+ def foreachWidth(f: Width => Unit): Unit
}
abstract class GroundType extends Type {
val width: Width
- def mapType(f: Type => Type): Type = this
+ def mapType(f: Type => Type): Type = this
def foreachType(f: Type => Unit): Unit = ()
}
object GroundType {
def unapply(ground: GroundType): Option[Width] = Some(ground.width)
}
abstract class AggregateType extends Type {
- def mapWidth(f: Width => Width): Type = this
- def foreachWidth(f: Width => Unit): Unit = ()
+ def mapWidth(f: Width => Width): Type = this
+ def foreachWidth(f: Width => Unit): Unit = ()
}
case class UIntType(width: Width) extends GroundType with UseSerializer {
- def mapWidth(f: Width => Width): Type = UIntType(f(width))
- def foreachWidth(f: Width => Unit): Unit = f(width)
+ def mapWidth(f: Width => Width): Type = UIntType(f(width))
+ def foreachWidth(f: Width => Unit): Unit = f(width)
}
case class SIntType(width: Width) extends GroundType with UseSerializer {
- def mapWidth(f: Width => Width): Type = SIntType(f(width))
- def foreachWidth(f: Width => Unit): Unit = f(width)
+ def mapWidth(f: Width => Width): Type = SIntType(f(width))
+ def foreachWidth(f: Width => Unit): Unit = f(width)
}
case class FixedType(width: Width, point: Width) extends GroundType with UseSerializer {
def mapWidth(f: Width => Width): Type = FixedType(f(width), f(point))
@@ -790,21 +844,21 @@ case class IntervalType(lower: Bound, upper: Bound, point: Width) extends Ground
case Open(l) => s"(${dec2string(l)}, "
case Closed(l) => s"[${dec2string(l)}, "
case UnknownBound => s"[?, "
- case _ => s"[?, "
+ case _ => s"[?, "
}
val upperString = upper match {
case Open(u) => s"${dec2string(u)})"
case Closed(u) => s"${dec2string(u)}]"
case UnknownBound => s"?]"
- case _ => s"?]"
+ case _ => s"?]"
}
val bounds = (lower, upper) match {
case (k1: IsKnown, k2: IsKnown) => lowerString + upperString
case _ => ""
}
val pointString = point match {
- case IntWidth(i) => "." + i.toString
- case _ => ""
+ case IntWidth(i) => "." + i.toString
+ case _ => ""
}
"Interval" + bounds + pointString
}
@@ -813,35 +867,43 @@ case class IntervalType(lower: Bound, upper: Bound, point: Width) extends Ground
private def precision: Option[BigDecimal] = point match {
case IntWidth(width) =>
val bp = width.toInt
- if(bp >= 0) Some(BigDecimal(1) / BigDecimal(BigInt(1) << bp)) else Some(BigDecimal(BigInt(1) << -bp))
+ if (bp >= 0) Some(BigDecimal(1) / BigDecimal(BigInt(1) << bp)) else Some(BigDecimal(BigInt(1) << -bp))
case other => None
}
def min: Option[BigDecimal] = (lower, precision) match {
- case (Open(a), Some(prec)) => a / prec match {
- case x if trim(x).isWhole => Some(a + prec) // add precision for open lower bound i.e. (-4 -> [3 for bp = 0
- case x => Some(x.setScale(0, CEILING) * prec) // Deal with unrepresentable bound representations (finite BP) -- new closed form l > original l
- }
+ case (Open(a), Some(prec)) =>
+ a / prec match {
+ case x if trim(x).isWhole => Some(a + prec) // add precision for open lower bound i.e. (-4 -> [3 for bp = 0
+ case x =>
+ Some(
+ x.setScale(0, CEILING) * prec
+ ) // Deal with unrepresentable bound representations (finite BP) -- new closed form l > original l
+ }
case (Closed(a), Some(prec)) => Some((a / prec).setScale(0, CEILING) * prec)
- case other => None
+ case other => None
}
def max: Option[BigDecimal] = (upper, precision) match {
- case (Open(a), Some(prec)) => a / prec match {
- case x if trim(x).isWhole => Some(a - prec) // subtract precision for open upper bound
- case x => Some(x.setScale(0, FLOOR) * prec)
- }
+ case (Open(a), Some(prec)) =>
+ a / prec match {
+ case x if trim(x).isWhole => Some(a - prec) // subtract precision for open upper bound
+ case x => Some(x.setScale(0, FLOOR) * prec)
+ }
case (Closed(a), Some(prec)) => Some((a / prec).setScale(0, FLOOR) * prec)
}
def minAdjusted: Option[BigInt] = min.map(_ * BigDecimal(BigInt(1) << bp) match {
case x if trim(x).isWhole | x.doubleValue == 0.0 => x.toBigInt
- case x => sys.error(s"MinAdjusted should be a whole number: $x. Min is $min. BP is $bp. Precision is $precision. Lower is ${lower}.")
+ case x =>
+ sys.error(
+ s"MinAdjusted should be a whole number: $x. Min is $min. BP is $bp. Precision is $precision. Lower is ${lower}."
+ )
})
def maxAdjusted: Option[BigInt] = max.map(_ * BigDecimal(BigInt(1) << bp) match {
case x if trim(x).isWhole => x.toBigInt
- case x => sys.error(s"MaxAdjusted should be a whole number: $x")
+ case x => sys.error(s"MaxAdjusted should be a whole number: $x")
})
/** If bounds are known, calculates the width, otherwise returns UnknownWidth */
@@ -854,48 +916,48 @@ case class IntervalType(lower: Bound, upper: Bound, point: Width) extends Ground
/** If bounds are known, returns a sequence of all possible values inside this interval */
lazy val range: Option[Seq[BigDecimal]] = (lower, upper, point) match {
case (l: IsKnown, u: IsKnown, p: IntWidth) =>
- if(min.get > max.get) Some(Nil) else Some(Range.BigDecimal(min.get, max.get, precision.get))
+ if (min.get > max.get) Some(Nil) else Some(Range.BigDecimal(min.get, max.get, precision.get))
case _ => None
}
- override def mapWidth(f: Width => Width): Type = this.copy(point = f(point))
- override def foreachWidth(f: Width => Unit): Unit = f(point)
+ override def mapWidth(f: Width => Width): Type = this.copy(point = f(point))
+ override def foreachWidth(f: Width => Unit): Unit = f(point)
}
case class BundleType(fields: Seq[Field]) extends AggregateType with UseSerializer {
def mapType(f: Type => Type): Type =
- BundleType(fields map (x => x.copy(tpe = f(x.tpe))))
- def foreachType(f: Type => Unit): Unit = fields.foreach{ x => f(x.tpe) }
+ BundleType(fields.map(x => x.copy(tpe = f(x.tpe))))
+ def foreachType(f: Type => Unit): Unit = fields.foreach { x => f(x.tpe) }
}
case class VectorType(tpe: Type, size: Int) extends AggregateType with UseSerializer {
- def mapType(f: Type => Type): Type = this.copy(tpe = f(tpe))
+ def mapType(f: Type => Type): Type = this.copy(tpe = f(tpe))
def foreachType(f: Type => Unit): Unit = f(tpe)
}
case object ClockType extends GroundType with UseSerializer {
val width = IntWidth(1)
- def mapWidth(f: Width => Width): Type = this
- def foreachWidth(f: Width => Unit): Unit = ()
+ def mapWidth(f: Width => Width): Type = this
+ def foreachWidth(f: Width => Unit): Unit = ()
}
/* Abstract reset, will be inferred to UInt<1> or AsyncReset */
case object ResetType extends GroundType with UseSerializer {
val width = IntWidth(1)
- def mapWidth(f: Width => Width): Type = this
- def foreachWidth(f: Width => Unit): Unit = ()
+ def mapWidth(f: Width => Width): Type = this
+ def foreachWidth(f: Width => Unit): Unit = ()
}
case object AsyncResetType extends GroundType with UseSerializer {
val width = IntWidth(1)
- def mapWidth(f: Width => Width): Type = this
- def foreachWidth(f: Width => Unit): Unit = ()
+ def mapWidth(f: Width => Width): Type = this
+ def foreachWidth(f: Width => Unit): Unit = ()
}
case class AnalogType(width: Width) extends GroundType with UseSerializer {
- def mapWidth(f: Width => Width): Type = AnalogType(f(width))
- def foreachWidth(f: Width => Unit): Unit = f(width)
+ def mapWidth(f: Width => Width): Type = AnalogType(f(width))
+ def foreachWidth(f: Width => Unit): Unit = f(width)
}
case object UnknownType extends Type with UseSerializer {
- def mapType(f: Type => Type): Type = this
- def mapWidth(f: Width => Width): Type = this
- def foreachType(f: Type => Unit): Unit = ()
- def foreachWidth(f: Width => Unit): Unit = ()
+ def mapType(f: Type => Type): Type = this
+ def mapWidth(f: Width => Width): Type = this
+ def foreachType(f: Type => Unit): Unit = ()
+ def foreachWidth(f: Width => Unit): Unit = ()
}
/** [[Port]] Direction */
@@ -909,11 +971,14 @@ case object Output extends Direction {
/** [[DefModule]] Port */
case class Port(
- info: Info,
- name: String,
- direction: Direction,
- tpe: Type) extends FirrtlNode with IsDeclaration with UseSerializer {
- def mapType(f: Type => Type): Port = Port(info, name, direction, f(tpe))
+ info: Info,
+ name: String,
+ direction: Direction,
+ tpe: Type)
+ extends FirrtlNode
+ with IsDeclaration
+ with UseSerializer {
+ def mapType(f: Type => Type): Port = Port(info, name, direction, f(tpe))
def mapString(f: String => String): Port = Port(info, f(name), direction, tpe)
}
@@ -921,12 +986,16 @@ case class Port(
sealed abstract class Param extends FirrtlNode {
def name: String
}
+
/** Integer (of any width) Parameter */
case class IntParam(name: String, value: BigInt) extends Param with UseSerializer
+
/** IEEE Double Precision Parameter (for Verilog real) */
case class DoubleParam(name: String, value: Double) extends Param with UseSerializer
+
/** String Parameter */
case class StringParam(name: String, value: StringLit) extends Param with UseSerializer
+
/** Raw String Parameter
* Useful for Verilog type parameters
* @note Firrtl doesn't guarantee anything about this String being legal in any backend
@@ -935,59 +1004,65 @@ case class RawStringParam(name: String, value: String) extends Param with UseSer
/** Base class for modules */
abstract class DefModule extends FirrtlNode with IsDeclaration {
- val info : Info
- val name : String
- val ports : Seq[Port]
- def mapStmt(f: Statement => Statement): DefModule
- def mapPort(f: Port => Port): DefModule
- def mapString(f: String => String): DefModule
- def mapInfo(f: Info => Info): DefModule
- def foreachStmt(f: Statement => Unit): Unit
- def foreachPort(f: Port => Unit): Unit
- def foreachString(f: String => Unit): Unit
- def foreachInfo(f: Info => Unit): Unit
+ val info: Info
+ val name: String
+ val ports: Seq[Port]
+ def mapStmt(f: Statement => Statement): DefModule
+ def mapPort(f: Port => Port): DefModule
+ def mapString(f: String => String): DefModule
+ def mapInfo(f: Info => Info): DefModule
+ def foreachStmt(f: Statement => Unit): Unit
+ def foreachPort(f: Port => Unit): Unit
+ def foreachString(f: String => Unit): Unit
+ def foreachInfo(f: Info => Unit): Unit
}
+
/** Internal Module
*
* An instantiable hardware block
*/
case class Module(info: Info, name: String, ports: Seq[Port], body: Statement) extends DefModule with UseSerializer {
- def mapStmt(f: Statement => Statement): DefModule = this.copy(body = f(body))
- def mapPort(f: Port => Port): DefModule = this.copy(ports = ports map f)
- def mapString(f: String => String): DefModule = this.copy(name = f(name))
- def mapInfo(f: Info => Info): DefModule = this.copy(f(info))
- def foreachStmt(f: Statement => Unit): Unit = f(body)
- def foreachPort(f: Port => Unit): Unit = ports.foreach(f)
- def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ def mapStmt(f: Statement => Statement): DefModule = this.copy(body = f(body))
+ def mapPort(f: Port => Port): DefModule = this.copy(ports = ports.map(f))
+ def mapString(f: String => String): DefModule = this.copy(name = f(name))
+ def mapInfo(f: Info => Info): DefModule = this.copy(f(info))
+ def foreachStmt(f: Statement => Unit): Unit = f(body)
+ def foreachPort(f: Port => Unit): Unit = ports.foreach(f)
+ def foreachString(f: String => Unit): Unit = f(name)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
+
/** External Module
*
* Generally used for Verilog black boxes
* @param defname Defined name of the external module (ie. the name Firrtl will emit)
*/
case class ExtModule(
- info: Info,
- name: String,
- ports: Seq[Port],
- defname: String,
- params: Seq[Param]) extends DefModule with UseSerializer {
- def mapStmt(f: Statement => Statement): DefModule = this
- def mapPort(f: Port => Port): DefModule = this.copy(ports = ports map f)
- def mapString(f: String => String): DefModule = this.copy(name = f(name))
- def mapInfo(f: Info => Info): DefModule = this.copy(f(info))
- def foreachStmt(f: Statement => Unit): Unit = ()
- def foreachPort(f: Port => Unit): Unit = ports.foreach(f)
- def foreachString(f: String => Unit): Unit = f(name)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ info: Info,
+ name: String,
+ ports: Seq[Port],
+ defname: String,
+ params: Seq[Param])
+ extends DefModule
+ with UseSerializer {
+ def mapStmt(f: Statement => Statement): DefModule = this
+ def mapPort(f: Port => Port): DefModule = this.copy(ports = ports.map(f))
+ def mapString(f: String => String): DefModule = this.copy(name = f(name))
+ def mapInfo(f: Info => Info): DefModule = this.copy(f(info))
+ def foreachStmt(f: Statement => Unit): Unit = ()
+ def foreachPort(f: Port => Unit): Unit = ports.foreach(f)
+ def foreachString(f: String => Unit): Unit = f(name)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class Circuit(info: Info, modules: Seq[DefModule], main: String)
- extends FirrtlNode with HasInfo with UseSerializer {
- def mapModule(f: DefModule => DefModule): Circuit = this.copy(modules = modules map f)
- def mapString(f: String => String): Circuit = this.copy(main = f(main))
- def mapInfo(f: Info => Info): Circuit = this.copy(f(info))
- def foreachModule(f: DefModule => Unit): Unit = modules foreach f
- def foreachString(f: String => Unit): Unit = f(main)
- def foreachInfo(f: Info => Unit): Unit = f(info)
+ extends FirrtlNode
+ with HasInfo
+ with UseSerializer {
+ def mapModule(f: DefModule => DefModule): Circuit = this.copy(modules = modules.map(f))
+ def mapString(f: String => String): Circuit = this.copy(main = f(main))
+ def mapInfo(f: Info => Info): Circuit = this.copy(f(info))
+ def foreachModule(f: DefModule => Unit): Unit = modules.foreach(f)
+ def foreachString(f: String => Unit): Unit = f(main)
+ def foreachInfo(f: Info => Unit): Unit = f(info)
}
diff --git a/src/main/scala/firrtl/ir/Serializer.scala b/src/main/scala/firrtl/ir/Serializer.scala
index ea304cf3..bf9a57c1 100644
--- a/src/main/scala/firrtl/ir/Serializer.scala
+++ b/src/main/scala/firrtl/ir/Serializer.scala
@@ -13,19 +13,19 @@ object Serializer {
val builder = new StringBuilder()
val indent = 0
node match {
- case n : Info => s(n)(builder, indent)
- case n : StringLit => s(n)(builder, indent)
- case n : Expression => s(n)(builder, indent)
- case n : Statement => s(n)(builder, indent)
- case n : Width => s(n)(builder, indent)
- case n : Orientation => s(n)(builder, indent)
- case n : Field => s(n)(builder, indent)
- case n : Type => s(n)(builder, indent)
- case n : Direction => s(n)(builder, indent)
- case n : Port => s(n)(builder, indent)
- case n : Param => s(n)(builder, indent)
- case n : DefModule => s(n)(builder, indent)
- case n : Circuit => s(n)(builder, indent)
+ case n: Info => s(n)(builder, indent)
+ case n: StringLit => s(n)(builder, indent)
+ case n: Expression => s(n)(builder, indent)
+ case n: Statement => s(n)(builder, indent)
+ case n: Width => s(n)(builder, indent)
+ case n: Orientation => s(n)(builder, indent)
+ case n: Field => s(n)(builder, indent)
+ case n: Type => s(n)(builder, indent)
+ case n: Direction => s(n)(builder, indent)
+ case n: Port => s(n)(builder, indent)
+ case n: Param => s(n)(builder, indent)
+ case n: DefModule => s(n)(builder, indent)
+ case n: Circuit => s(n)(builder, indent)
}
builder.toString()
}
@@ -39,16 +39,16 @@ object Serializer {
private def flattenInfo(infos: Seq[Info]): Seq[FileInfo] = infos.flatMap {
case NoInfo => Seq()
- case f : FileInfo => Seq(f)
+ case f: FileInfo => Seq(f)
case MultiInfo(infos) => flattenInfo(infos)
}
private def s(node: Info)(implicit b: StringBuilder, indent: Int): Unit = node match {
- case f : FileInfo => b ++= " @[" ; b ++= f.escaped ; b ++= "]"
+ case f: FileInfo => b ++= " @["; b ++= f.escaped; b ++= "]"
case NoInfo => // empty string
- case m : MultiInfo =>
+ case m: MultiInfo =>
val infos = m.flatten
- if(infos.nonEmpty) {
+ if (infos.nonEmpty) {
val lastId = infos.length - 1
b ++= " @["
infos.zipWithIndex.foreach { case (f, i) => b ++= f.escaped; if (i < lastId) b += ' ' }
@@ -61,103 +61,113 @@ object Serializer {
private def s(node: Expression)(implicit b: StringBuilder, indent: Int): Unit = node match {
case Reference(name, _, _, _) => b ++= name
case DoPrim(op, args, consts, _) =>
- b ++= op.toString ; b += '(' ; s(args, ", ", consts.isEmpty) ; s(consts, ", ") ; b += ')'
+ b ++= op.toString; b += '('; s(args, ", ", consts.isEmpty); s(consts, ", "); b += ')'
case UIntLiteral(value, width) =>
- b ++= "UInt" ; s(width) ; b ++= "(\"h" ; b ++= value.toString(16) ; b ++= "\")"
- case SubField(expr, name, _, _) => s(expr) ; b += '.' ; b ++= name
- case SubIndex(expr, value, _, _) => s(expr) ; b += '[' ; b ++= value.toString ; b += ']'
- case SubAccess(expr, index, _, _) => s(expr) ; b += '[' ; s(index) ; b += ']'
+ b ++= "UInt"; s(width); b ++= "(\"h"; b ++= value.toString(16); b ++= "\")"
+ case SubField(expr, name, _, _) => s(expr); b += '.'; b ++= name
+ case SubIndex(expr, value, _, _) => s(expr); b += '['; b ++= value.toString; b += ']'
+ case SubAccess(expr, index, _, _) => s(expr); b += '['; s(index); b += ']'
case Mux(cond, tval, fval, _) =>
- b ++= "mux(" ; s(cond) ; b ++= ", " ; s(tval) ; b ++= ", " ; s(fval) ; b += ')'
- case ValidIf(cond, value, _) => b ++= "validif(" ; s(cond) ; b ++= ", " ; s(value) ; b += ')'
+ b ++= "mux("; s(cond); b ++= ", "; s(tval); b ++= ", "; s(fval); b += ')'
+ case ValidIf(cond, value, _) => b ++= "validif("; s(cond); b ++= ", "; s(value); b += ')'
case SIntLiteral(value, width) =>
- b ++= "SInt" ; s(width) ; b ++= "(\"h" ; b ++= value.toString(16) ; b ++= "\")"
+ b ++= "SInt"; s(width); b ++= "(\"h"; b ++= value.toString(16); b ++= "\")"
case FixedLiteral(value, width, point) =>
- b ++= "Fixed" ; s(width) ; sPoint(point)
- b ++= "(\"h" ; b ++= value.toString(16) ; b ++= "\")"
+ b ++= "Fixed"; s(width); sPoint(point)
+ b ++= "(\"h"; b ++= value.toString(16); b ++= "\")"
// WIR
- case firrtl.WVoid => b ++= "VOID"
- case firrtl.WInvalid => b ++= "INVALID"
+ case firrtl.WVoid => b ++= "VOID"
+ case firrtl.WInvalid => b ++= "INVALID"
case firrtl.EmptyExpression => b ++= "EMPTY"
}
private def s(node: Statement)(implicit b: StringBuilder, indent: Int): Unit = node match {
- case DefNode(info, name, value) => b ++= "node " ; b ++= name ; b ++= " = " ; s(value) ; s(info)
- case Connect(info, loc, expr) => s(loc) ; b ++= " <= " ; s(expr) ; s(info)
+ case DefNode(info, name, value) => b ++= "node "; b ++= name; b ++= " = "; s(value); s(info)
+ case Connect(info, loc, expr) => s(loc); b ++= " <= "; s(expr); s(info)
case Conditionally(info, pred, conseq, alt) =>
- b ++= "when " ; s(pred) ; b ++= " :" ; s(info)
- newLineAndIndent(1) ; s(conseq)(b, indent + 1)
- if(alt != EmptyStmt) {
- newLineAndIndent() ; b ++= "else :"
- newLineAndIndent(1) ; s(alt)(b, indent + 1)
+ b ++= "when "; s(pred); b ++= " :"; s(info)
+ newLineAndIndent(1); s(conseq)(b, indent + 1)
+ if (alt != EmptyStmt) {
+ newLineAndIndent(); b ++= "else :"
+ newLineAndIndent(1); s(alt)(b, indent + 1)
}
- case EmptyStmt => b ++= "skip"
+ case EmptyStmt => b ++= "skip"
case Block(Seq()) => b ++= "skip"
case Block(stmts) =>
val it = stmts.iterator
- while(it.hasNext) {
+ while (it.hasNext) {
s(it.next)
- if(it.hasNext) newLineAndIndent()
+ if (it.hasNext) newLineAndIndent()
}
case Stop(info, ret, clk, en) =>
- b ++= "stop(" ; s(clk) ; b ++= ", " ; s(en) ; b ++= ", " ; b ++= ret.toString ; b += ')' ; s(info)
+ b ++= "stop("; s(clk); b ++= ", "; s(en); b ++= ", "; b ++= ret.toString; b += ')'; s(info)
case Print(info, string, args, clk, en) =>
- b ++= "printf(" ; s(clk) ; b ++= ", " ; s(en) ; b ++= ", " ; b ++= string.escape
- if(args.nonEmpty) b ++= ", " ; s(args, ", ") ; b += ')' ; s(info)
- case IsInvalid(info, expr) => s(expr) ; b ++= " is invalid" ; s(info)
- case DefWire(info, name, tpe) => b ++= "wire " ; b ++= name ; b ++= " : " ; s(tpe) ; s(info)
+ b ++= "printf("; s(clk); b ++= ", "; s(en); b ++= ", "; b ++= string.escape
+ if (args.nonEmpty) b ++= ", "; s(args, ", "); b += ')'; s(info)
+ case IsInvalid(info, expr) => s(expr); b ++= " is invalid"; s(info)
+ case DefWire(info, name, tpe) => b ++= "wire "; b ++= name; b ++= " : "; s(tpe); s(info)
case DefRegister(info, name, tpe, clock, reset, init) =>
- b ++= "reg " ; b ++= name ; b ++= " : " ; s(tpe) ; b ++= ", " ; s(clock) ; b ++= " with :" ; newLineAndIndent(1)
- b ++= "reset => (" ; s(reset) ; b ++= ", " ; s(init) ; b += ')' ; s(info)
- case DefInstance(info, name, module, _) => b ++= "inst " ; b ++= name ; b ++= " of " ; b ++= module ; s(info)
- case DefMemory(info, name, dataType, depth, writeLatency, readLatency, readers, writers,
- readwriters, readUnderWrite) =>
- b ++= "mem " ; b ++= name ; b ++= " :" ; s(info) ; newLineAndIndent(1)
- b ++= "data-type => " ; s(dataType) ; newLineAndIndent(1)
- b ++= "depth => " ; b ++= depth.toString() ; newLineAndIndent(1)
- b ++= "read-latency => " ; b ++= readLatency.toString ; newLineAndIndent(1)
- b ++= "write-latency => " ; b ++= writeLatency.toString ; newLineAndIndent(1)
- readers.foreach{ r => b ++= "reader => " ; b ++= r ; newLineAndIndent(1) }
- writers.foreach{ w => b ++= "writer => " ; b ++= w ; newLineAndIndent(1) }
- readwriters.foreach{ r => b ++= "readwriter => " ; b ++= r ; newLineAndIndent(1) }
- b ++= "read-under-write => " ; b ++= readUnderWrite.toString
- case PartialConnect(info, loc, expr) => s(loc) ; b ++= " <- " ; s(expr) ; s(info)
- case Attach(info, exprs) =>
+ b ++= "reg "; b ++= name; b ++= " : "; s(tpe); b ++= ", "; s(clock); b ++= " with :"; newLineAndIndent(1)
+ b ++= "reset => ("; s(reset); b ++= ", "; s(init); b += ')'; s(info)
+ case DefInstance(info, name, module, _) => b ++= "inst "; b ++= name; b ++= " of "; b ++= module; s(info)
+ case DefMemory(
+ info,
+ name,
+ dataType,
+ depth,
+ writeLatency,
+ readLatency,
+ readers,
+ writers,
+ readwriters,
+ readUnderWrite
+ ) =>
+ b ++= "mem "; b ++= name; b ++= " :"; s(info); newLineAndIndent(1)
+ b ++= "data-type => "; s(dataType); newLineAndIndent(1)
+ b ++= "depth => "; b ++= depth.toString(); newLineAndIndent(1)
+ b ++= "read-latency => "; b ++= readLatency.toString; newLineAndIndent(1)
+ b ++= "write-latency => "; b ++= writeLatency.toString; newLineAndIndent(1)
+ readers.foreach { r => b ++= "reader => "; b ++= r; newLineAndIndent(1) }
+ writers.foreach { w => b ++= "writer => "; b ++= w; newLineAndIndent(1) }
+ readwriters.foreach { r => b ++= "readwriter => "; b ++= r; newLineAndIndent(1) }
+ b ++= "read-under-write => "; b ++= readUnderWrite.toString
+ case PartialConnect(info, loc, expr) => s(loc); b ++= " <- "; s(expr); s(info)
+ case Attach(info, exprs) =>
// exprs should never be empty since the attach statement takes *at least* two signals according to the spec
- b ++= "attach (" ; s(exprs, ", ") ; b += ')' ; s(info)
+ b ++= "attach ("; s(exprs, ", "); b += ')'; s(info)
case Verification(op, info, clk, pred, en, msg) =>
- b ++= op.toString ; b += '(' ; s(List(clk, pred, en), ", ", false) ; b ++= msg.escape
- b += ')' ; s(info)
+ b ++= op.toString; b += '('; s(List(clk, pred, en), ", ", false); b ++= msg.escape
+ b += ')'; s(info)
// WIR
case firrtl.CDefMemory(info, name, tpe, size, seq, readUnderWrite) =>
- if(seq) b ++= "smem " else b ++= "cmem "
- b ++= name ; b ++= " : " ; s(tpe) ; b ++= " [" ; b ++= size.toString() ; b += ']' ; s(info)
+ if (seq) b ++= "smem " else b ++= "cmem "
+ b ++= name; b ++= " : "; s(tpe); b ++= " ["; b ++= size.toString(); b += ']'; s(info)
case firrtl.CDefMPort(info, name, _, mem, exps, direction) =>
- b ++= direction.serialize ; b ++= " mport " ; b ++= name ; b ++= " = " ; b ++= mem
- b += '[' ; s(exps.head) ; b ++= "], " ; s(exps(1)) ; s(info)
+ b ++= direction.serialize; b ++= " mport "; b ++= name; b ++= " = "; b ++= mem
+ b += '['; s(exps.head); b ++= "], "; s(exps(1)); s(info)
case firrtl.WDefInstanceConnector(info, name, module, tpe, portCons) =>
- b ++= "inst " ; b ++= name ; b ++= " of " ; b ++= module ; b ++= " with " ; s(tpe) ; b ++= " connected to ("
- s(portCons.map(_._2), ", ") ; b += ')' ; s(info)
+ b ++= "inst "; b ++= name; b ++= " of "; b ++= module; b ++= " with "; s(tpe); b ++= " connected to ("
+ s(portCons.map(_._2), ", "); b += ')'; s(info)
}
private def s(node: Width)(implicit b: StringBuilder, indent: Int): Unit = node match {
case IntWidth(width) => b += '<'; b ++= width.toString(); b += '>'
- case UnknownWidth => // empty string
- case CalcWidth(arg) => b ++= "calcw("; s(arg); b += ')'
- case VarWidth(name) => b += '<'; b ++= name; b += '>'
+ case UnknownWidth => // empty string
+ case CalcWidth(arg) => b ++= "calcw("; s(arg); b += ')'
+ case VarWidth(name) => b += '<'; b ++= name; b += '>'
}
private def sPoint(node: Width)(implicit b: StringBuilder, indent: Int): Unit = node match {
case IntWidth(width) => b ++= "<<"; b ++= width.toString(); b ++= ">>"
- case UnknownWidth => // empty string
- case CalcWidth(arg) => b ++= "calcw("; s(arg); b += ')'
- case VarWidth(name) => b ++= "<<"; b ++= name; b ++= ">>"
+ case UnknownWidth => // empty string
+ case CalcWidth(arg) => b ++= "calcw("; s(arg); b += ')'
+ case VarWidth(name) => b ++= "<<"; b ++= name; b ++= ">>"
}
private def s(node: Orientation)(implicit b: StringBuilder, indent: Int): Unit = node match {
case Default => // empty string
- case Flip => b ++= "flip "
+ case Flip => b ++= "flip "
}
private def s(node: Field)(implicit b: StringBuilder, indent: Int): Unit = node match {
@@ -169,19 +179,19 @@ object Serializer {
case UIntType(width: Width) => b ++= "UInt"; s(width)
case SIntType(width: Width) => b ++= "SInt"; s(width)
case FixedType(width, point) => b ++= "Fixed"; s(width); sPoint(point)
- case BundleType(fields) => b ++= "{ "; sField(fields, ", "); b += '}'
- case VectorType(tpe, size) => s(tpe); b += '['; b ++= size.toString; b += ']'
- case ClockType => b ++= "Clock"
- case ResetType => b ++= "Reset"
- case AsyncResetType => b ++= "AsyncReset"
- case AnalogType(width) => b ++= "Analog"; s(width)
- case UnknownType => b += '?'
+ case BundleType(fields) => b ++= "{ "; sField(fields, ", "); b += '}'
+ case VectorType(tpe, size) => s(tpe); b += '['; b ++= size.toString; b += ']'
+ case ClockType => b ++= "Clock"
+ case ResetType => b ++= "Reset"
+ case AsyncResetType => b ++= "AsyncReset"
+ case AnalogType(width) => b ++= "Analog"; s(width)
+ case UnknownType => b += '?'
// the IntervalType has a complicated custom serialization method which does not recurse
case i: IntervalType => b ++= i.serialize
}
private def s(node: Direction)(implicit b: StringBuilder, indent: Int): Unit = node match {
- case Input => b ++= "input"
+ case Input => b ++= "input"
case Output => b ++= "output"
}
@@ -191,50 +201,50 @@ object Serializer {
}
private def s(node: Param)(implicit b: StringBuilder, indent: Int): Unit = node match {
- case IntParam(name, value) => b ++= "parameter " ; b ++= name ; b ++= " = " ; b ++= value.toString
- case DoubleParam(name, value) => b ++= "parameter " ; b ++= name ; b ++= " = " ; b ++= value.toString
- case StringParam(name, value) => b ++= "parameter " ; b ++= name ; b ++= " = " ; b ++= value.escape
+ case IntParam(name, value) => b ++= "parameter "; b ++= name; b ++= " = "; b ++= value.toString
+ case DoubleParam(name, value) => b ++= "parameter "; b ++= name; b ++= " = "; b ++= value.toString
+ case StringParam(name, value) => b ++= "parameter "; b ++= name; b ++= " = "; b ++= value.escape
case RawStringParam(name, value) =>
- b ++= "parameter " ; b ++= name ; b ++= " = "
- b += '\'' ; b ++= value.replace("'", "\\'") ; b += '\''
+ b ++= "parameter "; b ++= name; b ++= " = "
+ b += '\''; b ++= value.replace("'", "\\'"); b += '\''
}
private def s(node: DefModule)(implicit b: StringBuilder, indent: Int): Unit = node match {
case Module(info, name, ports, body) =>
- b ++= "module " ; b ++= name ; b ++= " :" ; s(info)
- ports.foreach{ p => newLineAndIndent(1) ; s(p) }
+ b ++= "module "; b ++= name; b ++= " :"; s(info)
+ ports.foreach { p => newLineAndIndent(1); s(p) }
newLineNoIndent() // add a new line between port declaration and body
- newLineAndIndent(1) ; s(body)(b, indent + 1)
+ newLineAndIndent(1); s(body)(b, indent + 1)
case ExtModule(info, name, ports, defname, params) =>
- b ++= "extmodule " ; b ++= name ; b ++= " :" ; s(info)
- ports.foreach{ p => newLineAndIndent(1) ; s(p) }
- newLineAndIndent(1) ; b ++= "defname = " ; b ++= defname
- params.foreach{ p => newLineAndIndent(1) ; s(p) }
+ b ++= "extmodule "; b ++= name; b ++= " :"; s(info)
+ ports.foreach { p => newLineAndIndent(1); s(p) }
+ newLineAndIndent(1); b ++= "defname = "; b ++= defname
+ params.foreach { p => newLineAndIndent(1); s(p) }
}
private def s(node: Circuit)(implicit b: StringBuilder, indent: Int): Unit = node match {
case Circuit(info, modules, main) =>
- b ++= "circuit " ; b ++= main ; b ++= " :" ; s(info)
- if(modules.nonEmpty) {
- newLineAndIndent(1) ; s(modules.head)(b, indent + 1)
- modules.drop(1).foreach{m => newLineNoIndent(); newLineAndIndent(1) ; s(m)(b, indent + 1) }
+ b ++= "circuit "; b ++= main; b ++= " :"; s(info)
+ if (modules.nonEmpty) {
+ newLineAndIndent(1); s(modules.head)(b, indent + 1)
+ modules.drop(1).foreach { m => newLineNoIndent(); newLineAndIndent(1); s(m)(b, indent + 1) }
}
}
// serialize constraints
private def s(const: Constraint)(implicit b: StringBuilder): Unit = const match {
// Bounds
- case UnknownBound => b += '?'
- case CalcBound(arg) => b ++= "calcb(" ; s(arg) ; b += ')'
+ case UnknownBound => b += '?'
+ case CalcBound(arg) => b ++= "calcb("; s(arg); b += ')'
case VarBound(name) => b ++= name
- case Open(value) => b ++ "o(" ; b ++= value.toString ; b += ')'
- case Closed(value) => b ++ "c(" ; b ++= value.toString ; b += ')'
- case other => other.serialize
+ case Open(value) => b ++ "o("; b ++= value.toString; b += ')'
+ case Closed(value) => b ++ "c("; b ++= value.toString; b += ')'
+ case other => other.serialize
}
/** create a new line with the appropriate indent */
private def newLineAndIndent(inc: Int = 0)(implicit b: StringBuilder, indent: Int): Unit = {
- b += NewLine ; doIndent(inc)
+ b += NewLine; doIndent(inc)
}
private def newLineNoIndent()(implicit b: StringBuilder): Unit = b += NewLine
@@ -245,32 +255,37 @@ object Serializer {
}
/** serialize firrtl Expression nodes with a custom separator and the option to include the separator at the end */
- private def s(nodes: Iterable[Expression], sep: String, noFinalSep: Boolean = true)
- (implicit b: StringBuilder, indent: Int): Unit = {
+ private def s(
+ nodes: Iterable[Expression],
+ sep: String,
+ noFinalSep: Boolean = true
+ )(
+ implicit b: StringBuilder,
+ indent: Int
+ ): Unit = {
val it = nodes.iterator
- while(it.hasNext) {
+ while (it.hasNext) {
s(it.next())
- if(!noFinalSep || it.hasNext) b ++= sep
+ if (!noFinalSep || it.hasNext) b ++= sep
}
}
/** serialize firrtl Field nodes with a custom separator and the option to include the separator at the end */
@inline
- private def sField(nodes: Iterable[Field], sep: String)
- (implicit b: StringBuilder, indent: Int): Unit = {
+ private def sField(nodes: Iterable[Field], sep: String)(implicit b: StringBuilder, indent: Int): Unit = {
val it = nodes.iterator
- while(it.hasNext) {
+ while (it.hasNext) {
s(it.next())
- if(it.hasNext) b ++= sep
+ if (it.hasNext) b ++= sep
}
}
/** serialize BigInts with a custom separator */
private def s(consts: Iterable[BigInt], sep: String)(implicit b: StringBuilder): Unit = {
val it = consts.iterator
- while(it.hasNext) {
+ while (it.hasNext) {
b ++= it.next().toString()
- if(it.hasNext) b ++= sep
+ if (it.hasNext) b ++= sep
}
}
}
diff --git a/src/main/scala/firrtl/ir/StructuralHash.scala b/src/main/scala/firrtl/ir/StructuralHash.scala
index 1b38dec1..f1ed91f3 100644
--- a/src/main/scala/firrtl/ir/StructuralHash.scala
+++ b/src/main/scala/firrtl/ir/StructuralHash.scala
@@ -24,7 +24,7 @@ import scala.collection.mutable
* of the same circuit and thus all modules referred to in DefInstance are the same.
*
* @author Kevin Laeufer <laeufer@cs.berkeley.edu>
- * */
+ */
object StructuralHash {
def sha256(node: DefModule, moduleRename: String => String = identity): HashCode = {
val m = MessageDigest.getInstance(SHA256)
@@ -59,19 +59,19 @@ object StructuralHash {
private val SHA256 = "SHA-256"
private def hash(node: FirrtlNode, h: Hasher, rename: String => String): Unit = node match {
- case n : Expression => new StructuralHash(h, rename).hash(n)
- case n : Statement => new StructuralHash(h, rename).hash(n)
- case n : Type => new StructuralHash(h, rename).hash(n)
- case n : Width => new StructuralHash(h, rename).hash(n)
- case n : Orientation => new StructuralHash(h, rename).hash(n)
- case n : Field => new StructuralHash(h, rename).hash(n)
- case n : Direction => new StructuralHash(h, rename).hash(n)
- case n : Port => new StructuralHash(h, rename).hash(n)
- case n : Param => new StructuralHash(h, rename).hash(n)
- case _ : Info => throw new RuntimeException("The structural hash of Info is meaningless.")
- case n : DefModule => new StructuralHash(h, rename).hash(n)
- case n : Circuit => hashCircuit(n, h, rename)
- case n : StringLit => h.update(n.toString)
+ case n: Expression => new StructuralHash(h, rename).hash(n)
+ case n: Statement => new StructuralHash(h, rename).hash(n)
+ case n: Type => new StructuralHash(h, rename).hash(n)
+ case n: Width => new StructuralHash(h, rename).hash(n)
+ case n: Orientation => new StructuralHash(h, rename).hash(n)
+ case n: Field => new StructuralHash(h, rename).hash(n)
+ case n: Direction => new StructuralHash(h, rename).hash(n)
+ case n: Port => new StructuralHash(h, rename).hash(n)
+ case n: Param => new StructuralHash(h, rename).hash(n)
+ case _: Info => throw new RuntimeException("The structural hash of Info is meaningless.")
+ case n: DefModule => new StructuralHash(h, rename).hash(n)
+ case n: Circuit => hashCircuit(n, h, rename)
+ case n: StringLit => h.update(n.toString)
}
private def hashModuleAndPortNames(m: DefModule, h: Hasher, rename: String => String): Unit = {
@@ -85,9 +85,9 @@ object StructuralHash {
}
private def hashPortTypeName(tpe: Type, h: String => Unit): Unit = tpe match {
- case BundleType(fields) => fields.foreach{ f => h(f.name) ; hashPortTypeName(f.tpe, h) }
- case VectorType(vt, _) => hashPortTypeName(vt, h)
- case _ => // ignore ground types since they do not have field names nor sub-types
+ case BundleType(fields) => fields.foreach { f => h(f.name); hashPortTypeName(f.tpe, h) }
+ case VectorType(vt, _) => hashPortTypeName(vt, h)
+ case _ => // ignore ground types since they do not have field names nor sub-types
}
private def hashCircuit(c: Circuit, h: Hasher, rename: String => String): Unit = {
@@ -101,8 +101,8 @@ object StructuralHash {
}
}
- private val primOpToId = PrimOps.builtinPrimOps.zipWithIndex.map{ case (op, i) => op -> (-i -1).toByte }.toMap
- assert(primOpToId.values.max == -1, "PrimOp nodes use ids -1 ... -50")
+ private val primOpToId = PrimOps.builtinPrimOps.zipWithIndex.map { case (op, i) => op -> (-i - 1).toByte }.toMap
+ assert(primOpToId.values.max == -1, "PrimOp nodes use ids -1 ... -50")
assert(primOpToId.values.min >= -50, "PrimOp nodes use ids -1 ... -50")
private def primOp(p: PrimOp): Byte = primOpToId(p)
@@ -110,7 +110,7 @@ object StructuralHash {
private def verificationOp(op: Formal.Value): Byte = op match {
case Formal.Assert => 0
case Formal.Assume => 1
- case Formal.Cover => 2
+ case Formal.Cover => 2
}
}
@@ -129,14 +129,14 @@ private class MDHashCode(code: Array[Byte]) extends HashCode {
/** Generic hashing interface which allows us to use different backends to trade of speed and collision resistance */
private trait Hasher {
- def update(b: Byte): Unit
- def update(i: Int): Unit
- def update(l: Long): Unit
- def update(s: String): Unit
+ def update(b: Byte): Unit
+ def update(i: Int): Unit
+ def update(l: Long): Unit
+ def update(s: String): Unit
def update(b: Array[Byte]): Unit
def update(d: Double): Unit = update(java.lang.Double.doubleToRawLongBits(d))
- def update(i: BigInt): Unit = update(i.toByteArray)
- def update(b: Boolean): Unit = if(b) update(1.toByte) else update(0.toByte)
+ def update(i: BigInt): Unit = update(i.toByteArray)
+ def update(b: Boolean): Unit = if (b) update(1.toByte) else update(0.toByte)
def update(i: BigDecimal): Unit = {
// this might be broken, tried to borrow some code from BigDecimal.computeHashCode
val temp = i.bigDecimal.stripTrailingZeros()
@@ -149,14 +149,14 @@ private trait Hasher {
private class MessageDigestHasher(m: MessageDigest) extends Hasher {
override def update(b: Byte): Unit = m.update(b)
override def update(i: Int): Unit = {
- m.update(((i >> 0) & 0xff).toByte)
- m.update(((i >> 8) & 0xff).toByte)
+ m.update(((i >> 0) & 0xff).toByte)
+ m.update(((i >> 8) & 0xff).toByte)
m.update(((i >> 16) & 0xff).toByte)
m.update(((i >> 24) & 0xff).toByte)
}
override def update(l: Long): Unit = {
- m.update(((l >> 0) & 0xff).toByte)
- m.update(((l >> 8) & 0xff).toByte)
+ m.update(((l >> 0) & 0xff).toByte)
+ m.update(((l >> 8) & 0xff).toByte)
m.update(((l >> 16) & 0xff).toByte)
m.update(((l >> 24) & 0xff).toByte)
m.update(((l >> 32) & 0xff).toByte)
@@ -165,42 +165,47 @@ private class MessageDigestHasher(m: MessageDigest) extends Hasher {
m.update(((l >> 56) & 0xff).toByte)
}
// the encoding of the bytes should not matter as long as we are on the same platform
- override def update(s: String): Unit = m.update(s.getBytes())
+ override def update(s: String): Unit = m.update(s.getBytes())
override def update(b: Array[Byte]): Unit = m.update(b)
}
-class StructuralHash private(h: Hasher, renameModule: String => String) {
+class StructuralHash private (h: Hasher, renameModule: String => String) {
// replace identifiers with incrementing integers
private val nameToInt = mutable.HashMap[String, Int]()
private var nameCounter: Int = 0
- @inline private def n(name: String): Unit = hash(nameToInt.getOrElseUpdate(name, {
- val ii = nameCounter
- nameCounter = nameCounter + 1
- ii
- }))
+ @inline private def n(name: String): Unit = hash(
+ nameToInt.getOrElseUpdate(
+ name, {
+ val ii = nameCounter
+ nameCounter = nameCounter + 1
+ ii
+ }
+ )
+ )
// internal convenience methods
- @inline private def id(b: Byte): Unit = h.update(b)
- @inline private def hash(i: Int): Unit = h.update(i)
- @inline private def hash(b: Boolean): Unit = h.update(b)
- @inline private def hash(d: Double): Unit = h.update(d)
- @inline private def hash(i: BigInt): Unit = h.update(i)
+ @inline private def id(b: Byte): Unit = h.update(b)
+ @inline private def hash(i: Int): Unit = h.update(i)
+ @inline private def hash(b: Boolean): Unit = h.update(b)
+ @inline private def hash(d: Double): Unit = h.update(d)
+ @inline private def hash(i: BigInt): Unit = h.update(i)
@inline private def hash(i: BigDecimal): Unit = h.update(i)
- @inline private def hash(s: String): Unit = h.update(s)
+ @inline private def hash(s: String): Unit = h.update(s)
private def hash(node: Expression): Unit = node match {
- case Reference(name, _, _, _) => id(0) ; n(name)
+ case Reference(name, _, _, _) => id(0); n(name)
case DoPrim(op, args, consts, _) =>
// no need to hash the number of arguments or constants since that is implied by the op
- id(1) ; h.update(StructuralHash.primOp(op)) ; args.foreach(hash) ; consts.foreach(hash)
- case UIntLiteral(value, width) => id(2) ; hash(value) ; hash(width)
+ id(1); h.update(StructuralHash.primOp(op)); args.foreach(hash); consts.foreach(hash)
+ case UIntLiteral(value, width) => id(2); hash(value); hash(width)
// We hash bundles as if fields are accessed by their index.
// Thus we need to also hash field accesses that way.
// This has the side-effect that `x.y` might hash to the same value as `z.r`, for example if the
// types are `x: {y: UInt<1>, ...}` and `z: {r: UInt<1>, ...}` respectively.
// They do not hash to the same value if the type of `z` is e.g., `z: {..., r: UInt<1>, ...}`
// as that would have the `r` field at a different index.
- case SubField(expr, name, _, _) => id(3) ; hash(expr)
+ case SubField(expr, name, _, _) =>
+ id(3); hash(expr)
// find field index and hash that instead of the field name
val fields = expr.tpe match {
case b: BundleType => b.fields
@@ -209,93 +214,115 @@ class StructuralHash private(h: Hasher, renameModule: String => String) {
}
val index = fields.zipWithIndex.find(_._1.name == name).map(_._2).get
hash(index)
- case SubIndex(expr, value, _, _) => id(4) ; hash(expr) ; hash(value)
- case SubAccess(expr, index, _, _) => id(5) ; hash(expr) ; hash(index)
- case Mux(cond, tval, fval, _) => id(6) ; hash(cond) ; hash(tval) ; hash(fval)
- case ValidIf(cond, value, _) => id(7) ; hash(cond) ; hash(value)
- case SIntLiteral(value, width) => id(8) ; hash(value) ; hash(width)
- case FixedLiteral(value, width, point) => id(9) ; hash(value) ; hash(width) ; hash(point)
+ case SubIndex(expr, value, _, _) => id(4); hash(expr); hash(value)
+ case SubAccess(expr, index, _, _) => id(5); hash(expr); hash(index)
+ case Mux(cond, tval, fval, _) => id(6); hash(cond); hash(tval); hash(fval)
+ case ValidIf(cond, value, _) => id(7); hash(cond); hash(value)
+ case SIntLiteral(value, width) => id(8); hash(value); hash(width)
+ case FixedLiteral(value, width, point) => id(9); hash(value); hash(width); hash(point)
// WIR
- case firrtl.WVoid => id(10)
- case firrtl.WInvalid => id(11)
+ case firrtl.WVoid => id(10)
+ case firrtl.WInvalid => id(11)
case firrtl.EmptyExpression => id(12)
// VRandom is used in the Emitter
- case firrtl.VRandom(width) => id(13) ; hash(width)
+ case firrtl.VRandom(width) => id(13); hash(width)
// ids 14 ... 19 are reserved for future Expression nodes
}
private def hash(node: Statement): Unit = node match {
// all info fields are ignore
- case DefNode(_, name, value) => id(20) ; n(name) ; hash(value)
- case Connect(_, loc, expr) => id(21) ; hash(loc) ; hash(expr)
+ case DefNode(_, name, value) => id(20); n(name); hash(value)
+ case Connect(_, loc, expr) => id(21); hash(loc); hash(expr)
// we place the unique id 23 between conseq and alt to distinguish between them in case conseq is empty
// we place the unique id 24 after alt to distinguish between alt and the next statement in case alt is empty
- case Conditionally(_, pred, conseq, alt) => id(22) ; hash(pred) ; hash(conseq) ; id(23) ; hash(alt) ; id(24)
- case EmptyStmt => // empty statements are ignored
- case Block(stmts) => stmts.foreach(hash) // block structure is ignored
- case Stop(_, ret, clk, en) => id(25) ; hash(ret) ; hash(clk) ; hash(en)
- case Print(_, string, args, clk, en) =>
+ case Conditionally(_, pred, conseq, alt) => id(22); hash(pred); hash(conseq); id(23); hash(alt); id(24)
+ case EmptyStmt => // empty statements are ignored
+ case Block(stmts) => stmts.foreach(hash) // block structure is ignored
+ case Stop(_, ret, clk, en) => id(25); hash(ret); hash(clk); hash(en)
+ case Print(_, string, args, clk, en) =>
// the string is part of the side effect and thus part of the circuit behavior
- id(26) ; hash(string.string) ; hash(args.length) ; args.foreach(hash) ; hash(clk) ; hash(en)
- case IsInvalid(_, expr) => id(27) ; hash(expr)
- case DefWire(_, name, tpe) => id(28) ; n(name) ; hash(tpe)
+ id(26); hash(string.string); hash(args.length); args.foreach(hash); hash(clk); hash(en)
+ case IsInvalid(_, expr) => id(27); hash(expr)
+ case DefWire(_, name, tpe) => id(28); n(name); hash(tpe)
case DefRegister(_, name, tpe, clock, reset, init) =>
- id(29) ; n(name) ; hash(tpe) ; hash(clock) ; hash(reset) ; hash(init)
+ id(29); n(name); hash(tpe); hash(clock); hash(reset); hash(init)
case DefInstance(_, name, module, _) =>
// Module is in the global namespace which is why we cannot replace it with a numeric id.
// However, it might have been renamed as part of the dedup consolidation.
- id(30) ; n(name) ; hash(renameModule(module))
+ id(30); n(name); hash(renameModule(module))
// descriptions on statements are ignores
case firrtl.DescribedStmt(_, stmt) => hash(stmt)
- case DefMemory(_, name, dataType, depth, writeLatency, readLatency, readers, writers,
- readwriters, readUnderWrite) =>
- id(30) ; n(name) ; hash(dataType) ; hash(depth) ; hash(writeLatency) ; hash(readLatency)
- hash(readers.length) ; readers.foreach(hash)
- hash(writers.length) ; writers.foreach(hash)
- hash(readwriters.length) ; readwriters.foreach(hash)
+ case DefMemory(
+ _,
+ name,
+ dataType,
+ depth,
+ writeLatency,
+ readLatency,
+ readers,
+ writers,
+ readwriters,
+ readUnderWrite
+ ) =>
+ id(30); n(name); hash(dataType); hash(depth); hash(writeLatency); hash(readLatency)
+ hash(readers.length); readers.foreach(hash)
+ hash(writers.length); writers.foreach(hash)
+ hash(readwriters.length); readwriters.foreach(hash)
hash(readUnderWrite)
- case PartialConnect(_, loc, expr) => id(31) ; hash(loc) ; hash(expr)
- case Attach(_, exprs) => id(32) ; hash(exprs.length) ; exprs.foreach(hash)
+ case PartialConnect(_, loc, expr) => id(31); hash(loc); hash(expr)
+ case Attach(_, exprs) => id(32); hash(exprs.length); exprs.foreach(hash)
// WIR
case firrtl.CDefMemory(_, name, tpe, size, seq, readUnderWrite) =>
- id(33) ; n(name) ; hash(tpe); hash(size) ; hash(seq) ; hash(readUnderWrite)
+ id(33); n(name); hash(tpe); hash(size); hash(seq); hash(readUnderWrite)
case firrtl.CDefMPort(_, name, _, mem, exps, direction) =>
// the type of the MPort depends only on the memory (in well types firrtl) and can thus be ignored
- id(34) ; n(name) ; n(mem) ; hash(exps.length) ; exps.foreach(hash) ; hash(direction)
+ id(34); n(name); n(mem); hash(exps.length); exps.foreach(hash); hash(direction)
// DefAnnotatedMemory from MemIR.scala
- case firrtl.passes.memlib.DefAnnotatedMemory(_, name, dataType, depth, writeLatency, readLatency, readers, writers,
- readwriters, readUnderWrite, maskGran, memRef) =>
- id(35) ; n(name) ; hash(dataType) ; hash(depth) ; hash(writeLatency) ; hash(readLatency)
- hash(readers.length) ; readers.foreach(hash)
- hash(writers.length) ; writers.foreach(hash)
- hash(readwriters.length) ; readwriters.foreach(hash)
+ case firrtl.passes.memlib.DefAnnotatedMemory(
+ _,
+ name,
+ dataType,
+ depth,
+ writeLatency,
+ readLatency,
+ readers,
+ writers,
+ readwriters,
+ readUnderWrite,
+ maskGran,
+ memRef
+ ) =>
+ id(35); n(name); hash(dataType); hash(depth); hash(writeLatency); hash(readLatency)
+ hash(readers.length); readers.foreach(hash)
+ hash(writers.length); writers.foreach(hash)
+ hash(readwriters.length); readwriters.foreach(hash)
hash(readUnderWrite.toString)
- hash(maskGran.size) ; maskGran.foreach(hash)
- hash(memRef.size) ; memRef.foreach{ case (a, b) => hash(a) ; hash(b) }
+ hash(maskGran.size); maskGran.foreach(hash)
+ hash(memRef.size); memRef.foreach { case (a, b) => hash(a); hash(b) }
case Verification(op, _, clk, pred, en, msg) =>
- id(36) ; hash(StructuralHash.verificationOp(op)) ; hash(clk) ; hash(pred) ; hash(en) ; hash(msg.string)
+ id(36); hash(StructuralHash.verificationOp(op)); hash(clk); hash(pred); hash(en); hash(msg.string)
// ids 37 ... 39 are reserved for future Statement nodes
}
// ReadUnderWrite is never used in place of a FirrtlNode and thus we can start a new id namespace
private def hash(ruw: ReadUnderWrite.Value): Unit = ruw match {
- case ReadUnderWrite.New => id(0)
- case ReadUnderWrite.Old => id(1)
+ case ReadUnderWrite.New => id(0)
+ case ReadUnderWrite.Old => id(1)
case ReadUnderWrite.Undefined => id(2)
}
private def hash(node: Width): Unit = node match {
- case IntWidth(width) => id(40) ; hash(width)
- case UnknownWidth => id(41)
- case CalcWidth(arg) => id(42) ; hash(arg)
+ case IntWidth(width) => id(40); hash(width)
+ case UnknownWidth => id(41)
+ case CalcWidth(arg) => id(42); hash(arg)
// we are hashing the name of the `VarWidth` instead of using `n` since these Vars exist in a different namespace
- case VarWidth(name) => id(43) ; hash(name)
+ case VarWidth(name) => id(43); hash(name)
// ids 44 + 45 are reserved for future Width nodes
}
private def hash(node: Orientation): Unit = node match {
case Default => id(46)
- case Flip => id(47)
+ case Flip => id(47)
}
private def hash(node: Field): Unit = {
@@ -306,81 +333,81 @@ class StructuralHash private(h: Hasher, renameModule: String => String) {
// has been used in the Dedup pass for a long time.
// This position-based notion of equality requires us to replace field names with field indexes when hashing
// SubField accesses.
- id(48) ; hash(node.flip) ; hash(node.tpe)
+ id(48); hash(node.flip); hash(node.tpe)
}
private def hash(node: Type): Unit = node match {
// Types
- case UIntType(width: Width) => id(50) ; hash(width)
- case SIntType(width: Width) => id(51) ; hash(width)
- case FixedType(width, point) => id(52) ; hash(width) ; hash(point)
- case BundleType(fields) => id(53) ; hash(fields.length) ; fields.foreach(hash)
- case VectorType(tpe, size) => id(54) ; hash(tpe) ; hash(size)
- case ClockType => id(55)
- case ResetType => id(56)
- case AsyncResetType => id(57)
- case AnalogType(width) => id(58) ; hash(width)
- case UnknownType => id(59)
- case IntervalType(lower, upper, point) => id(60) ; hash(lower) ; hash(upper) ; hash(point)
+ case UIntType(width: Width) => id(50); hash(width)
+ case SIntType(width: Width) => id(51); hash(width)
+ case FixedType(width, point) => id(52); hash(width); hash(point)
+ case BundleType(fields) => id(53); hash(fields.length); fields.foreach(hash)
+ case VectorType(tpe, size) => id(54); hash(tpe); hash(size)
+ case ClockType => id(55)
+ case ResetType => id(56)
+ case AsyncResetType => id(57)
+ case AnalogType(width) => id(58); hash(width)
+ case UnknownType => id(59)
+ case IntervalType(lower, upper, point) => id(60); hash(lower); hash(upper); hash(point)
// ids 61 ... 65 are reserved for future Type nodes
}
private def hash(node: Direction): Unit = node match {
- case Input => id(66)
+ case Input => id(66)
case Output => id(67)
}
private def hash(node: Port): Unit = {
- id(68) ; n(node.name) ; hash(node.direction) ; hash(node.tpe)
+ id(68); n(node.name); hash(node.direction); hash(node.tpe)
}
private def hash(node: Param): Unit = node match {
- case IntParam(name, value) => id(70) ; n(name) ; hash(value)
- case DoubleParam(name, value) => id(71) ; n(name) ; hash(value)
- case StringParam(name, value) => id(72) ; n(name) ; hash(value.string)
- case RawStringParam(name, value) => id(73) ; n(name) ; hash(value)
+ case IntParam(name, value) => id(70); n(name); hash(value)
+ case DoubleParam(name, value) => id(71); n(name); hash(value)
+ case StringParam(name, value) => id(72); n(name); hash(value.string)
+ case RawStringParam(name, value) => id(73); n(name); hash(value)
// id 74 is reserved for future use
}
private def hash(node: DefModule): Unit = node match {
// the module name is ignored since it does not affect module functionality
case Module(_, _name, ports, body) =>
- id(75) ; hash(ports.length) ; ports.foreach(hash) ; hash(body)
+ id(75); hash(ports.length); ports.foreach(hash); hash(body)
// the module name is ignored since it does not affect module functionality
case ExtModule(_, name, ports, defname, params) =>
- id(76) ; hash(ports.length) ; ports.foreach(hash) ; hash(defname)
- hash(params.length) ; params.foreach(hash)
+ id(76); hash(ports.length); ports.foreach(hash); hash(defname)
+ hash(params.length); params.foreach(hash)
}
// id 127 is reserved for Circuit nodes
private def hash(d: firrtl.MPortDir): Unit = d match {
- case firrtl.MInfer => id(-70)
- case firrtl.MRead => id(-71)
- case firrtl.MWrite => id(-72)
+ case firrtl.MInfer => id(-70)
+ case firrtl.MRead => id(-71)
+ case firrtl.MWrite => id(-72)
case firrtl.MReadWrite => id(-73)
}
private def hash(c: firrtl.constraint.Constraint): Unit = c match {
case b: Bound => hash(b) /* uses ids -80 ... -84 */
case firrtl.constraint.IsAdd(known, maxs, mins, others) =>
- id(-85) ; hash(known.nonEmpty) ; known.foreach(hash)
- hash(maxs.length) ; maxs.foreach(hash)
- hash(mins.length) ; mins.foreach(hash)
- hash(others.length) ; others.foreach(hash)
- case firrtl.constraint.IsFloor(child, dummyArg) => id(-86) ; hash(child) ; hash(dummyArg)
- case firrtl.constraint.IsKnown(decimal) => id(-87) ; hash(decimal)
- case firrtl.constraint.IsNeg(child, dummyArg) => id(-88) ; hash(child) ; hash(dummyArg)
- case firrtl.constraint.IsPow(child, dummyArg) => id(-89) ; hash(child) ; hash(dummyArg)
- case firrtl.constraint.IsVar(str) => id(-90) ; n(str)
+ id(-85); hash(known.nonEmpty); known.foreach(hash)
+ hash(maxs.length); maxs.foreach(hash)
+ hash(mins.length); mins.foreach(hash)
+ hash(others.length); others.foreach(hash)
+ case firrtl.constraint.IsFloor(child, dummyArg) => id(-86); hash(child); hash(dummyArg)
+ case firrtl.constraint.IsKnown(decimal) => id(-87); hash(decimal)
+ case firrtl.constraint.IsNeg(child, dummyArg) => id(-88); hash(child); hash(dummyArg)
+ case firrtl.constraint.IsPow(child, dummyArg) => id(-89); hash(child); hash(dummyArg)
+ case firrtl.constraint.IsVar(str) => id(-90); n(str)
}
private def hash(b: Bound): Unit = b match {
case UnknownBound => id(-80)
- case CalcBound(arg) => id(-81) ; hash(arg)
+ case CalcBound(arg) => id(-81); hash(arg)
// we are hashing the name of the `VarBound` instead of using `n` since these Vars exist in a different namespace
- case VarBound(name) => id(-82) ; hash(name)
- case Open(value) => id(-83) ; hash(value)
- case Closed(value) => id(-84) ; hash(value)
+ case VarBound(name) => id(-82); hash(name)
+ case Open(value) => id(-83); hash(value)
+ case Closed(value) => id(-84); hash(value)
}
-} \ No newline at end of file
+}