summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/internal/firrtl
diff options
context:
space:
mode:
authorJim Lawson2016-06-20 11:08:46 -0700
committerJim Lawson2016-06-20 11:08:46 -0700
commitd408d73a171535bd7c2ba9d0037c194022b8a62f (patch)
tree81885a99ec56e89532bc3fa338f22b163dcc4d1f /chiselFrontend/src/main/scala/chisel3/internal/firrtl
parentb5a534914795d9d17f4dfe623525f1b804e4c60f (diff)
Rename chisel3 package.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/internal/firrtl')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala190
1 files changed, 190 insertions, 0 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
new file mode 100644
index 00000000..70e9938b
--- /dev/null
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -0,0 +1,190 @@
+// See LICENSE for license details.
+
+package chisel.internal.firrtl
+
+import chisel._
+import core._
+import chisel.internal._
+import chisel.internal.sourceinfo.{SourceInfo, NoSourceInfo}
+
+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,
+ s"The literal value ${num} was elaborated with a specificed width of ${widthArg.get} bits, but at least ${minWidth} bits are required.")
+ }
+}
+
+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 = s"<${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 {
+ def sourceInfo: SourceInfo
+}
+abstract class Definition extends Command {
+ def id: HasId
+ def name: String = id.getRef.name
+}
+case class DefPrim[T <: Data](sourceInfo: SourceInfo, id: T, op: PrimOp, args: Arg*) extends Definition
+case class DefInvalid(sourceInfo: SourceInfo, arg: Arg) extends Command
+case class DefWire(sourceInfo: SourceInfo, id: Data) extends Definition
+case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg) extends Definition
+case class DefRegInit(sourceInfo: SourceInfo, id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition
+case class DefMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition
+case class DefSeqMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition
+case class DefMemPort[T <: Data](sourceInfo: SourceInfo, id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition
+case class DefInstance(sourceInfo: SourceInfo, id: Module, ports: Seq[Port]) extends Definition
+case class WhenBegin(sourceInfo: SourceInfo, pred: Arg) extends Command
+case class WhenEnd(sourceInfo: SourceInfo) extends Command
+case class Connect(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
+case class BulkConnect(sourceInfo: SourceInfo, loc1: Node, loc2: Node) extends Command
+case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
+case class Stop(sourceInfo: SourceInfo, clk: Arg, ret: Int) 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 Printf(sourceInfo: SourceInfo, clk: Arg, formatIn: String, ids: Seq[Arg]) extends Command {
+ require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values")
+ def format: String = {
+ def escaped(x: Char) = {
+ require(x.toInt >= 0)
+ if (x == '"' || x == '\\') {
+ s"\\${x}"
+ } else if (x == '\n') {
+ "\\n"
+ } else {
+ require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved
+ x
+ }
+ }
+ formatIn.map(escaped _).mkString
+ }
+}
+
+case class Circuit(name: String, components: Seq[Component])