diff options
| author | Adam Izraelevitz | 2015-10-05 10:28:41 -0700 |
|---|---|---|
| committer | Adam Izraelevitz | 2015-10-05 10:28:41 -0700 |
| commit | 0a9dfbe9f58338fc8af11015f6e9227e0cb46ea4 (patch) | |
| tree | 6ecac3e05509202dc7ad94fb03f41300ebf89619 /src/main/scala/firrtl/Utils.scala | |
| parent | 0a9cc3d72fa2c6f19385efa8350f232e2e9faf10 (diff) | |
| parent | edd894af01d004b417c11f264c5302896f321c7d (diff) | |
Merge pull request #44 from jackkoenig/master
Add Scala implementation to firrtl repo
Diffstat (limited to 'src/main/scala/firrtl/Utils.scala')
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala new file mode 100644 index 00000000..916408bc --- /dev/null +++ b/src/main/scala/firrtl/Utils.scala @@ -0,0 +1,194 @@ +// Utility functions for FIRRTL IR + +/* TODO + * - Adopt style more similar to Chisel3 Emitter? + */ + +package firrtl + +import scala.collection.mutable.StringBuilder + +object Utils { + + implicit class BigIntUtils(bi: BigInt){ + def serialize(): String = + "\"h0" + bi.toString(16) + "\"" + } + + implicit class PrimOpUtils(op: PrimOp) { + def serialize(): String = { + op match { + case Add => "add" + case Sub => "sub" + case Addw => "addw" + case Subw => "subw" + case Mul => "mul" + case Div => "div" + case Mod => "mod" + case Quo => "quo" + case Rem => "rem" + case Lt => "lt" + case Leq => "leq" + case Gt => "gt" + case Geq => "geq" + case Eq => "eq" + case Neq => "neq" + case Mux => "mux" + case Pad => "pad" + case AsUInt => "asUInt" + case AsSInt => "asSInt" + case Shl => "shl" + case Shr => "shr" + case Dshl => "dshl" + case Dshr => "dshr" + case Cvt => "cvt" + case Neg => "neg" + case Not => "not" + case And => "and" + case Or => "or" + case Xor => "xor" + case Andr => "andr" + case Orr => "orr" + case Xorr => "xorr" + case Cat => "cat" + case Bit => "bit" + case Bits => "bits" + } + } + } + + implicit class ExpUtils(exp: Exp) { + def serialize(): String = + exp match { + case v: UIntValue => s"UInt<${v.width}>(${v.value.serialize})" + case v: SIntValue => s"SInt<${v.width}>(${v.value.serialize})" + case r: Ref => r.name + case s: Subfield => s"${s.exp.serialize}.${s.name}" + case s: Subindex => s"${s.exp.serialize}[${s.value}]" + case p: DoPrimOp => + s"${p.op.serialize}(" + (p.args.map(_.serialize) ++ p.consts.map(_.toString)).mkString(", ") + ")" + } + } + + // AccessorDir + implicit class AccessorDirUtils(dir: AccessorDir) { + def serialize(): String = + dir match { + case Infer => "infer" + case Read => "read" + case Write => "write" + case RdWr => "rdwr" + } + } + + + implicit class StmtUtils(stmt: Stmt) { + def serialize(): String = + stmt match { + case w: DefWire => s"wire ${w.name} : ${w.tpe.serialize}" + case r: DefReg => s"reg ${r.name} : ${r.tpe.serialize}, ${r.clock.serialize}, ${r.reset.serialize}" + case m: DefMemory => (if(m.seq) "smem" else "cmem") + + s" ${m.name} : ${m.tpe.serialize}, ${m.clock.serialize}" + case i: DefInst => s"inst ${i.name} of ${i.module.serialize}" + case n: DefNode => s"node ${n.name} = ${n.value.serialize}" + case p: DefPoison => s"poison ${p.name} : ${p.tpe.serialize}" + case a: DefAccessor => s"${a.dir.serialize} accessor ${a.name} = ${a.source.serialize}[${a.index.serialize}]" + case c: Connect => s"${c.lhs.serialize} := ${c.rhs.serialize}" + case o: OnReset => s"onreset ${o.lhs.serialize} := ${o.rhs.serialize}" + case b: BulkConnect => s"${b.lhs.serialize} <> ${b.rhs.serialize}" + case w: When => { + var str = new StringBuilder(s"when ${w.pred.serialize} : ") + withIndent { str ++= w.conseq.serialize } + if( w.alt != EmptyStmt ) { + str ++= newline + "else :" + withIndent { str ++= w.alt.serialize } + } + str.result + } + //case b: Block => b.stmts.map(newline ++ _.serialize).mkString + case b: Block => { + val s = new StringBuilder + b.stmts.foreach { s ++= newline ++ _.serialize } + s.result + } + case a: Assert => s"assert ${a.pred.serialize}" + case EmptyStmt => "skip" + } + } + + implicit class WidthUtils(w: Width) { + def serialize(): String = + w match { + case UnknownWidth => "?" + case w: IntWidth => w.width.toString + } + } + + implicit class FieldDirUtils(dir: FieldDir) { + def serialize(): String = + dir match { + case Reverse => "flip " + case Default => "" + } + } + + implicit class FieldUtils(field: Field) { + def serialize(): String = + s"${field.dir.serialize} ${field.name} : ${field.tpe.serialize}" + } + + implicit class TypeUtils(t: Type) { + def serialize(): String = { + val commas = ", " // for mkString in BundleType + t match { + case ClockType => "Clock" + case UnknownType => "UnknownType" + case t: UIntType => s"UInt<${t.width.serialize}>" + case t: SIntType => s"SInt<${t.width.serialize}>" + case t: BundleType => s"{ ${t.fields.map(_.serialize).mkString(commas)} }" + case t: VectorType => s"${t.tpe.serialize}[${t.size}]" + } + } + } + + implicit class PortDirUtils(p: PortDir) { + def serialize(): String = + p match { + case Input => "input" + case Output => "output" + } + } + + implicit class PortUtils(p: Port) { + def serialize(): String = + s"${p.dir.serialize} ${p.name} : ${p.tpe.serialize}" + } + + implicit class ModuleUtils(m: Module) { + def serialize(): String = { + var s = new StringBuilder(s"module ${m.name} : ") + withIndent { + s ++= m.ports.map(newline ++ _.serialize).mkString + s ++= newline ++ m.stmt.serialize + } + s.toString + } + } + + implicit class CircuitUtils(c: Circuit) { + def serialize(): String = { + var s = new StringBuilder(s"circuit ${c.name} : ") + //withIndent { c.modules.foreach(s ++= newline ++ newline ++ _.serialize) } + withIndent { s ++= newline ++ c.modules.map(_.serialize).mkString(newline + newline) } + s ++= newline ++ newline + s.toString + } + } + + private var indentLevel = 0 + private def newline = "\n" + (" " * indentLevel) + private def indent(): Unit = indentLevel += 1 + private def unindent() { require(indentLevel > 0); indentLevel -= 1 } + private def withIndent(f: => Unit) { indent(); f; unindent() } + +} |
