summaryrefslogtreecommitdiff
path: root/src/main/scala/Chisel/internal
diff options
context:
space:
mode:
authorAndrew Waterman2016-01-28 12:15:53 -0800
committerAndrew Waterman2016-01-28 12:15:53 -0800
commit7eff2b0a16e1ca982c227bd498720981c883686b (patch)
tree767a04718b16750b33dd4e2d629d3e836bb7f637 /src/main/scala/Chisel/internal
parent6d37cc8b9d731fa4c844f097b11057c46771961b (diff)
parent41674d5e130f64d7489fdb8583b8f4ad88b64aeb (diff)
Merge branch 'master' into scalastyle
Diffstat (limited to 'src/main/scala/Chisel/internal')
-rw-r--r--src/main/scala/Chisel/internal/Builder.scala7
-rw-r--r--src/main/scala/Chisel/internal/firrtl/Emitter.scala73
-rw-r--r--src/main/scala/Chisel/internal/firrtl/IR.scala170
3 files changed, 247 insertions, 3 deletions
diff --git a/src/main/scala/Chisel/internal/Builder.scala b/src/main/scala/Chisel/internal/Builder.scala
index 385e25a2..7e72b5e1 100644
--- a/src/main/scala/Chisel/internal/Builder.scala
+++ b/src/main/scala/Chisel/internal/Builder.scala
@@ -6,7 +6,7 @@ import scala.util.DynamicVariable
import scala.collection.mutable.{ArrayBuffer, HashMap}
import Chisel._
-import Chisel.firrtl._
+import Chisel.internal.firrtl._
private[Chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) {
private var i = 0L
@@ -50,7 +50,8 @@ private[Chisel] trait HasId {
private[Chisel] def setRef(imm: Arg) = _refMap.setRef(this, imm)
private[Chisel] def setRef(name: String) = _refMap.setRef(this, name)
private[Chisel] def setRef(parent: HasId, name: String) = _refMap.setField(parent, this, name)
- private[Chisel] def setRef(parent: HasId, index: Int) = _refMap.setIndex(parent, this, index)
+ private[Chisel] def setRef(parent: HasId, index: Int) = _refMap.setIndex(parent, this, ILit(index))
+ private[Chisel] def setRef(parent: HasId, index: UInt) = _refMap.setIndex(parent, this, index.ref)
private[Chisel] def getRef = _refMap(this)
}
@@ -66,7 +67,7 @@ class RefMap {
private[Chisel] def setField(parentid: HasId, id: HasId, name: String): Unit =
_refmap(id._id) = Slot(Node(parentid), name)
- private[Chisel] def setIndex(parentid: HasId, id: HasId, index: Int): Unit =
+ private[Chisel] def setIndex(parentid: HasId, id: HasId, index: Arg): Unit =
_refmap(id._id) = Index(Node(parentid), index)
def apply(id: HasId): Arg = _refmap(id._id)
diff --git a/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala
new file mode 100644
index 00000000..13d9fa8f
--- /dev/null
+++ b/src/main/scala/Chisel/internal/firrtl/Emitter.scala
@@ -0,0 +1,73 @@
+// See LICENSE for license details.
+
+package Chisel.internal.firrtl
+import Chisel._
+
+private class Emitter(circuit: Circuit) {
+ override def toString: String = res.toString
+
+ private def emitPort(e: Port): String =
+ s"${e.dir} ${e.id.getRef.name} : ${e.id.toType}"
+ private def emit(e: Command, ctx: Component): String = e match {
+ case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${e.args.map(_.fullName(ctx)).reduce(_ + ", " + _)})"
+ case e: DefWire => s"wire ${e.name} : ${e.id.toType}"
+ case e: DefReg => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}"
+ case e: DefRegInit => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))"
+ case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]"
+ case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}]"
+ case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}"
+ case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}"
+ case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}"
+ case e: Stop => s"stop(${e.clk.fullName(ctx)}, UInt<1>(1), ${e.ret})"
+ case e: Printf => s"""printf(${e.clk.fullName(ctx)}, UInt<1>(1), "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})"""
+ case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid"
+ case e: DefInstance => {
+ val modName = moduleMap.getOrElse(e.id.name, e.id.name)
+ s"inst ${e.name} of $modName"
+ }
+
+ case w: WhenBegin =>
+ indent()
+ s"when ${w.pred.fullName(ctx)} :"
+ case _: WhenEnd =>
+ unindent()
+ "skip"
+ }
+ private def emitBody(m: Component) = {
+ val me = new StringBuilder
+ withIndent {
+ for (p <- m.ports)
+ me ++= newline + emitPort(p)
+ me ++= newline
+ for (cmd <- m.commands)
+ me ++= newline + emit(cmd, m)
+ me ++= newline
+ }
+ me
+ }
+
+ private val bodyMap = collection.mutable.HashMap[StringBuilder, String]()
+ private val moduleMap = collection.mutable.HashMap[String, String]()
+
+ private def emit(m: Component): String = {
+ val body = emitBody(m)
+ bodyMap get body match {
+ case Some(name) =>
+ moduleMap(m.name) = name
+ ""
+ case None =>
+ bodyMap(body) = m.name
+ newline + s"module ${m.name} : " + body
+ }
+ }
+
+ 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() }
+
+ private val res = new StringBuilder(s"circuit ${circuit.name} : ")
+ withIndent { circuit.components.foreach(c => res ++= emit(c)) }
+ res ++= newline
+}
diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala
new file mode 100644
index 00000000..7bb273c0
--- /dev/null
+++ b/src/main/scala/Chisel/internal/firrtl/IR.scala
@@ -0,0 +1,170 @@
+// See LICENSE for license details.
+
+package Chisel.internal.firrtl
+import Chisel._
+import Chisel.internal._
+
+case class PrimOp(val name: String) {
+ override def toString: String = name
+}
+
+object PrimOp {
+ val AddOp = PrimOp("add")
+ val SubOp = PrimOp("sub")
+ val TailOp = PrimOp("tail")
+ val HeadOp = PrimOp("head")
+ val TimesOp = PrimOp("mul")
+ val DivideOp = PrimOp("div")
+ val RemOp = PrimOp("rem")
+ val ShiftLeftOp = PrimOp("shl")
+ val ShiftRightOp = PrimOp("shr")
+ val DynamicShiftLeftOp = PrimOp("dshl")
+ val DynamicShiftRightOp = PrimOp("dshr")
+ val BitAndOp = PrimOp("and")
+ val BitOrOp = PrimOp("or")
+ val BitXorOp = PrimOp("xor")
+ val BitNotOp = PrimOp("not")
+ val ConcatOp = PrimOp("cat")
+ val BitsExtractOp = PrimOp("bits")
+ val LessOp = PrimOp("lt")
+ val LessEqOp = PrimOp("leq")
+ val GreaterOp = PrimOp("gt")
+ val GreaterEqOp = PrimOp("geq")
+ val EqualOp = PrimOp("eq")
+ val PadOp = PrimOp("pad")
+ val NotEqualOp = PrimOp("neq")
+ val NegOp = PrimOp("neg")
+ val MultiplexOp = PrimOp("mux")
+ val XorReduceOp = PrimOp("xorr")
+ val ConvertOp = PrimOp("cvt")
+ val AsUIntOp = PrimOp("asUInt")
+ val AsSIntOp = PrimOp("asSInt")
+}
+
+abstract class Arg {
+ def fullName(ctx: Component): String = name
+ def name: String
+}
+
+case class Node(id: HasId) extends Arg {
+ override def fullName(ctx: Component): String = id.getRef.fullName(ctx)
+ def name: String = id.getRef.name
+}
+
+abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg {
+ private[Chisel] def forcedWidth = widthArg.known
+ private[Chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth)
+
+ protected def minWidth: Int
+ if (forcedWidth) {
+ require(widthArg.get >= minWidth)
+ }
+}
+
+case class ILit(n: BigInt) extends Arg {
+ def name: String = n.toString
+}
+
+case class ULit(n: BigInt, w: Width) extends LitArg(n, w) {
+ def name: String = "UInt<" + width + ">(\"h0" + num.toString(16) + "\")"
+ def minWidth: Int = 1 max n.bitLength
+
+ require(n >= 0, s"UInt literal ${n} is negative")
+}
+
+case class SLit(n: BigInt, w: Width) extends LitArg(n, w) {
+ def name: String = {
+ val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n
+ s"asSInt(${ULit(unsigned, width).name})"
+ }
+ def minWidth: Int = 1 + n.bitLength
+}
+
+case class Ref(name: String) extends Arg
+case class ModuleIO(mod: Module, name: String) extends Arg {
+ override def fullName(ctx: Component): String =
+ if (mod eq ctx.id) name else s"${mod.getRef.name}.$name"
+}
+case class Slot(imm: Node, name: String) extends Arg {
+ override def fullName(ctx: Component): String =
+ if (imm.fullName(ctx).isEmpty) name else s"${imm.fullName(ctx)}.${name}"
+}
+case class Index(imm: Arg, value: Arg) extends Arg {
+ def name: String = s"[$value]"
+ override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]"
+}
+
+object Width {
+ def apply(x: Int): Width = KnownWidth(x)
+ def apply(): Width = UnknownWidth()
+}
+
+sealed abstract class Width {
+ type W = Int
+ def max(that: Width): Width = this.op(that, _ max _)
+ def + (that: Width): Width = this.op(that, _ + _)
+ def + (that: Int): Width = this.op(this, (a, b) => a + that)
+ def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that))
+ def dynamicShiftLeft(that: Width): Width =
+ this.op(that, (a, b) => a + (1 << b) - 1)
+
+ def known: Boolean
+ def get: W
+ protected def op(that: Width, f: (W, W) => W): Width
+}
+
+sealed case class UnknownWidth() extends Width {
+ def known: Boolean = false
+ def get: Int = None.get
+ def op(that: Width, f: (W, W) => W): Width = this
+ override def toString: String = "?"
+}
+
+sealed case class KnownWidth(value: Int) extends Width {
+ require(value >= 0)
+ def known: Boolean = true
+ def get: Int = value
+ def op(that: Width, f: (W, W) => W): Width = that match {
+ case KnownWidth(x) => KnownWidth(f(value, x))
+ case _ => that
+ }
+ override def toString: String = value.toString
+}
+
+sealed abstract class MemPortDirection(name: String) {
+ override def toString: String = name
+}
+object MemPortDirection {
+ object READ extends MemPortDirection("read")
+ object WRITE extends MemPortDirection("write")
+ object RDWR extends MemPortDirection("rdwr")
+ object INFER extends MemPortDirection("infer")
+}
+
+abstract class Command
+abstract class Definition extends Command {
+ def id: HasId
+ def name: String = id.getRef.name
+}
+case class DefPrim[T <: Data](id: T, op: PrimOp, args: Arg*) extends Definition
+case class DefInvalid(arg: Arg) extends Command
+case class DefWire(id: Data) extends Definition
+case class DefReg(id: Data, clock: Arg) extends Definition
+case class DefRegInit(id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition
+case class DefMemory(id: HasId, t: Data, size: Int) extends Definition
+case class DefSeqMemory(id: HasId, t: Data, size: Int) extends Definition
+case class DefMemPort[T <: Data](id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition
+case class DefInstance(id: Module, ports: Seq[Port]) extends Definition
+case class WhenBegin(pred: Arg) extends Command
+case class WhenEnd() extends Command
+case class Connect(loc: Node, exp: Arg) extends Command
+case class BulkConnect(loc1: Node, loc2: Node) extends Command
+case class ConnectInit(loc: Node, exp: Arg) extends Command
+case class Stop(clk: Arg, ret: Int) extends Command
+case class Printf(clk: Arg, format: String, ids: Seq[Arg]) extends Command
+case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg
+case class Port(id: Data, dir: Direction)
+
+case class Circuit(name: String, components: Seq[Component], refMap: RefMap) {
+ def emit: String = new Emitter(this).toString
+}