diff options
| author | jackkoenig | 2016-01-23 15:56:55 -0800 |
|---|---|---|
| committer | jackkoenig | 2016-01-23 15:56:55 -0800 |
| commit | 544afdebc4d1b441e57123bd67bc48e8c036ffbb (patch) | |
| tree | 94abfbd655d4760c551869919ae23f97c245da9d /src/main/scala/Chisel/internal | |
| parent | 57c1770a964c44b4211453ab6f7f41289f21cd50 (diff) | |
Move firrtl subpackage to inside internal subpackage.
Diffstat (limited to 'src/main/scala/Chisel/internal')
| -rw-r--r-- | src/main/scala/Chisel/internal/Builder.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/Chisel/internal/firrtl/Emitter.scala | 73 | ||||
| -rw-r--r-- | src/main/scala/Chisel/internal/firrtl/IR.scala | 160 |
3 files changed, 234 insertions, 1 deletions
diff --git a/src/main/scala/Chisel/internal/Builder.scala b/src/main/scala/Chisel/internal/Builder.scala index 385e25a2..991a442f 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 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..c46f14ca --- /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: DefPoison[_] => s"poison ${e.name} : ${e.id.toType}" + case e: DefRegister => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}, ${e.reset.fullName(ctx)}" + case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}], ${e.clock.fullName(ctx)}" + case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}], ${e.clock.fullName(ctx)}" + case e: DefAccessor[_] => s"infer accessor ${e.name} = ${e.source.fullName(ctx)}[${e.index.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: ConnectInit => s"onreset ${e.loc.fullName(ctx)} := ${e.exp.fullName(ctx)}" + case e: Stop => s"stop(${e.clk.fullName(ctx)}, ${e.ret})" + case e: Printf => s"""printf(${e.clk.fullName(ctx)}, "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})""" + 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..be61d67b --- /dev/null +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -0,0 +1,160 @@ +// 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 AddModOp = PrimOp("addw") + val SubOp = PrimOp("sub") + val SubModOp = PrimOp("subw") + val TimesOp = PrimOp("mul") + val DivideOp = PrimOp("div") + val ModOp = PrimOp("mod") + 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 BitSelectOp = PrimOp("bit") + 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: Int) extends Arg { + def name: String = s"[$value]" + override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[$value]" +} + +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 +} + +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 DefWire(id: Data) extends Definition +case class DefRegister(id: Data, clock: Arg, reset: Arg) extends Definition +case class DefMemory(id: HasId, t: Data, size: Int, clock: Arg) extends Definition +case class DefSeqMemory(id: HasId, t: Data, size: Int, clock: Arg) extends Definition +case class DefAccessor[T <: Data](id: T, source: Node, direction: Direction, index: Arg) extends Definition +case class DefInstance(id: Module, ports: Seq[Port]) extends Definition +case class DefPoison[T <: Data](id: T) 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 +} |
