diff options
| author | Andrew Waterman | 2015-08-08 15:35:47 -0700 |
|---|---|---|
| committer | Andrew Waterman | 2015-08-08 15:43:56 -0700 |
| commit | 1e19f0b641c732f2ec4de25c85873e476567ecbc (patch) | |
| tree | 76e07ad3233e8fc8c0593ad19d7778ceaec60d27 /src | |
| parent | 1db280299c08ec08053cd23aac752ebcc8ae09f7 (diff) | |
DRY
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/Chisel/Core.scala | 141 | ||||
| -rw-r--r-- | src/main/scala/Chisel/FP.scala | 182 |
2 files changed, 117 insertions, 206 deletions
diff --git a/src/main/scala/Chisel/Core.scala b/src/main/scala/Chisel/Core.scala index 7fdd35bf..1589ea81 100644 --- a/src/main/scala/Chisel/Core.scala +++ b/src/main/scala/Chisel/Core.scala @@ -51,6 +51,10 @@ private object DynamicContext { def pushCommand(c: Command) { currentModuleVar.value.foreach(_._commands += c) } + def pushOp[T <: Data](cmd: DefPrim[T]) = { + pushCommand(cmd) + cmd.id + } def getParams: Parameters = currentParamsVar.value def paramsScope[T](p: Parameters)(body: => T): T = { @@ -78,6 +82,7 @@ object build { } import DynamicContext.pushCommand +import DynamicContext.pushOp /// CHISEL IR @@ -121,21 +126,20 @@ object PrimOp { import PrimOp._ abstract class Immediate { - def fullname: String - def name: String + def fullname: String = name def debugName = fullname + def name: String } abstract class Arg extends Immediate { - def fullname: String def name: String } case class Alias(id: Id) extends Arg { - def fullname = Builder.globalRefMap.getRefForId(id).fullname - def name = Builder.globalRefMap.getRefForId(id).name + override def fullname = Builder.globalRefMap.getRefForId(id).fullname override def debugName = Builder.globalRefMap.getRefForId(id).debugName - def emit: String = "Alias(" + id + ")" + def name = Builder.globalRefMap.getRefForId(id).name + def emit: String = s"Alias($id)" } abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { @@ -147,8 +151,11 @@ abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { require(widthArg.get >= minWidth) } +case class ILit(n: BigInt) extends Arg { + def name = n.toString +} + case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { - def fullname = name def name = "UInt<" + width + ">(\"h0" + num.toString(16) + "\")" def minWidth = 1 max n.bitLength @@ -156,7 +163,6 @@ case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { } case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { - def fullname = name def name = { val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n s"asSInt(${ULit(unsigned, width).name})" @@ -165,18 +171,17 @@ case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { } case class Ref(val name: String) extends Immediate { - def fullname = name } case class Slot(val imm: Immediate, val name: String) extends Immediate { - def fullname = + override def fullname = if (imm.fullname isEmpty) name else s"${imm.fullname}.${name}" override def debugName = if (imm.debugName isEmpty) name else s"${imm.debugName}.${name}" } case class Index(val imm: Immediate, val value: Int) extends Immediate { - def name = "[" + value + "]" - def fullname = imm.fullname + "[" + value + "]" - override def debugName = imm.debugName + "." + value + def name = s"[$value]" + override def fullname = s"${imm.fullname}[$value]" + override def debugName = s"${imm.debugName}.$value" } case class Port(id: Data, kind: Kind) @@ -237,7 +242,7 @@ case class DefUInt(id: Id, value: BigInt, width: Int) extends Definition case class DefSInt(id: Id, value: BigInt, width: Int) extends Definition case class DefFlo(id: Id, value: Float) extends Definition case class DefDbl(id: Id, value: Double) extends Definition -case class DefPrim(id: Id, kind: Kind, op: PrimOp, args: Seq[Arg], lits: Seq[BigInt]) extends Definition +case class DefPrim[T <: Data](id: T, op: PrimOp, args: Arg*) extends Definition case class DefWire(id: Id, kind: Kind) extends Definition case class DefRegister(id: Id, kind: Kind, clock: Clock, reset: Bool) extends Definition case class DefMemory(id: Id, kind: Kind, size: Int, clock: Clock) extends Definition @@ -254,12 +259,6 @@ case class ConnectInit(loc: Alias, exp: Arg) extends Command case class Component(name: String, ports: Seq[Port], commands: Seq[Command]) case class Circuit(components: Seq[Component], main: String) -object Commands { - val NoLits = Seq[BigInt]() -} - -import Commands._ - /// COMPONENTS sealed abstract class Direction(name: String) { @@ -334,7 +333,7 @@ abstract class Data(dirArg: Direction) extends Id { def width: Width final def getWidth = width.get - def flatten: IndexedSeq[Bits] + def flatten: IndexedSeq[UInt] def fromBits(n: Bits): this.type = { var i = 0 val wire = Wire(this.cloneType) @@ -504,7 +503,7 @@ class Vec[T <: Data](gen: => T, val length: Int) override def cloneType: this.type = Vec(gen, length).asInstanceOf[this.type] - override lazy val flatten: IndexedSeq[Bits] = + override lazy val flatten: IndexedSeq[UInt] = (0 until length).flatMap(i => this.apply(i).flatten) def read(idx: UInt): T = apply(idx) @@ -566,7 +565,9 @@ class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def != (other: UInt): Bool = !(this === other) } -abstract class Element(dirArg: Direction, val width: Width) extends Data(dirArg) +abstract class Element(dirArg: Direction, val width: Width) extends Data(dirArg) { + def flatten: IndexedSeq[UInt] = IndexedSeq(toBits) +} object Clock { def apply(dir: Direction = NO_DIR): Clock = new Clock(dir) @@ -575,7 +576,7 @@ object Clock { sealed class Clock(dirArg: Direction) extends Element(dirArg, Width(1)) { def cloneType: this.type = Clock(dirArg).asInstanceOf[this.type] def cloneTypeWidth(width: Width): this.type = cloneType - def flatten: IndexedSeq[Bits] = IndexedSeq() + override def flatten: IndexedSeq[UInt] = IndexedSeq() def toType: Kind = ClockType(isFlip) override def := (that: Data): Unit = that match { @@ -592,18 +593,11 @@ sealed abstract class Bits(dirArg: Direction, width: Width, lit: Option[LitArg]) def makeLit(value: BigInt): this.type def cloneType: this.type = cloneTypeWidth(width) - override def flatten: IndexedSeq[Bits] = IndexedSeq(this) - override def <> (that: Data): Unit = this := that - final def apply(x: BigInt): Bool = { + final def apply(x: BigInt): Bool = if (isLit()) Bool((litValue() >> x.toInt) & 1) - else { - val d = Bool() - pushCommand(DefPrim(d, d.toType, BitSelectOp, Seq(this.ref), Seq(x))) - d - } - } + else pushOp(DefPrim(Bool(), BitSelectOp, this.ref, ILit(x))) final def apply(x: Int): Bool = apply(BigInt(x)) final def apply(x: UInt): Bool = @@ -612,42 +606,21 @@ sealed abstract class Bits(dirArg: Direction, width: Width, lit: Option[LitArg]) final def apply(x: BigInt, y: BigInt): UInt = { val w = (x - y + 1).toInt if (isLit()) UInt((litValue >> y.toInt) & ((BigInt(1) << w) - 1), w) - else { - val d = UInt(width = w) - pushCommand(DefPrim(d, d.toType, BitsExtractOp, Seq(this.ref), Seq(x, y))) - d - } + else pushOp(DefPrim(UInt(width = w), BitsExtractOp, this.ref, ILit(x), ILit(y))) } final def apply(x: Int, y: Int): UInt = apply(BigInt(x), BigInt(y)) - private[Chisel] def unop(op: PrimOp, width: Width): this.type = { - val d = cloneTypeWidth(width) - pushCommand(DefPrim(d, d.toType, op, Seq(this.ref), NoLits)) - d - } - private[Chisel] def binop(op: PrimOp, other: BigInt, width: Width): this.type = { - val d = cloneTypeWidth(width) - pushCommand(DefPrim(d, d.toType, op, Seq(this.ref), Seq(other))) - d - } - private[Chisel] def binop(op: PrimOp, other: Bits, width: Width): this.type = { - val d = cloneTypeWidth(width) - pushCommand(DefPrim(d, d.toType, op, Seq(this.ref, other.ref), NoLits)) - d - } - private[Chisel] def compop(op: PrimOp, other: Bits): Bool = { - val d = new Bool(NO_DIR) - pushCommand(DefPrim(d, d.toType, op, Seq(this.ref, other.ref), NoLits)) - d - } - private[Chisel] def unimp(op: String) = - throwException(s"Operator ${op} unsupported for class ${getClass}") - private[Chisel] def redop(op: PrimOp): Bool = { - val d = new Bool(NO_DIR) - pushCommand(DefPrim(d, d.toType, op, Seq(this.ref), NoLits)) - d - } + private[Chisel] def unop(op: PrimOp, width: Width): this.type = + pushOp(DefPrim(cloneTypeWidth(width), op, this.ref)).asInstanceOf[this.type] + private[Chisel] def binop(op: PrimOp, other: BigInt, width: Width): this.type = + pushOp(DefPrim(cloneTypeWidth(width), op, this.ref, ILit(other))).asInstanceOf[this.type] + private[Chisel] def binop(op: PrimOp, other: Bits, width: Width): this.type = + pushOp(DefPrim(cloneTypeWidth(width), op, this.ref, other.ref)).asInstanceOf[this.type] + private[Chisel] def compop(op: PrimOp, other: Bits): Bool = + pushOp(DefPrim(Bool(), op, this.ref, other.ref)) + private[Chisel] def redop(op: PrimOp): Bool = + pushOp(DefPrim(Bool(), op, this.ref)) def unary_~ : this.type = unop(BitNotOp, width) def pad (other: Int): this.type = binop(PadOp, other, Width(other)) @@ -752,18 +725,8 @@ sealed class UInt(dir: Direction, width: Width, lit: Option[ULit] = None) extend def === (that: BitPat): Bool = that === this def != (that: BitPat): Bool = that != this - def zext(): SInt = { - val x = SInt(NO_DIR, width + 1) - pushCommand(DefPrim(x, x.toType, ConvertOp, Seq(ref), NoLits)) - x - } - - def asSInt(): SInt = { - val x = SInt(NO_DIR, width) - pushCommand(DefPrim(x, x.toType, AsSIntOp, Seq(ref), NoLits)) - x - } - + def zext(): SInt = pushOp(DefPrim(SInt(NO_DIR, width + 1), ConvertOp, ref)) + def asSInt(): SInt = pushOp(DefPrim(SInt(NO_DIR, width), AsSIntOp, ref)) def toSInt(): SInt = asSInt() def toUInt(): UInt = this def asUInt(): UInt = this @@ -841,11 +804,7 @@ sealed class SInt(dir: Direction, width: Width, lit: Option[SLit] = None) extend def >> (other: BigInt): SInt = this >> other.toInt def >> (other: UInt): SInt = binop(DynamicShiftRightOp, other, this.width) - def asUInt(): UInt = { - val x = UInt(NO_DIR, width) - pushCommand(DefPrim(x, x.toType, AsUIntOp, Seq(ref), NoLits)) - x - } + def asUInt(): UInt = pushOp(DefPrim(UInt(NO_DIR, width), AsUIntOp, ref)) def toUInt(): UInt = asUInt() def asSInt(): SInt = this def toSInt(): SInt = this @@ -897,8 +856,7 @@ object Mux { // These implementations are type-unsafe and rely on FIRRTL for type checking private def doMux[T <: Bits](cond: Bool, con: T, alt: T): T = { val d = alt.cloneTypeWidth(con.width max alt.width) - pushCommand(DefPrim(d, d.toType, MultiplexOp, Seq(cond.ref, con.ref, alt.ref), NoLits)) - d + pushOp(DefPrim(d, MultiplexOp, cond.ref, con.ref, alt.ref)) } // This returns an lvalue, which it most definitely should not private def doWhen[T <: Data](cond: Bool, con: T, alt: T): T = { @@ -916,13 +874,11 @@ object Cat { val left = apply(r.slice(0, r.length/2)) val right = apply(r.slice(r.length/2, r.length)) val w = left.width + right.width - if (left.isLit && right.isLit) { + + if (left.isLit && right.isLit) UInt((left.litValue() << right.getWidth) | right.litValue(), w) - } else { - val d = UInt(NO_DIR, w) - pushCommand(DefPrim(d, d.toType, ConcatOp, Seq(left.ref, right.ref), NoLits)) - d - } + else + pushOp(DefPrim(UInt(NO_DIR, w), ConcatOp, left.ref, right.ref)) } } } @@ -954,8 +910,7 @@ class Bundle extends Aggregate(NO_DIR) { def toType: BundleType = BundleType(this.toPorts, isFlip) - override def flatten: IndexedSeq[Bits] = - allElts.flatMap(_._2.flatten) + override def flatten: IndexedSeq[UInt] = allElts.flatMap(_._2.flatten) lazy val elements: ListMap[String, Data] = ListMap(allElts:_*) @@ -1149,7 +1104,7 @@ class Emitter(circuit: Circuit) { case e: DefSInt => s"node ${e.name} = SInt<${e.width}>(${e.value})" case e: DefFlo => s"node ${e.name} = Flo(${e.value})" case e: DefDbl => s"node ${e.name} = Dbl(${e.value})" - case e: DefPrim => s"node ${e.name} = ${emit(e.op)}(${join(e.args.map(x => emit(x)) ++ e.lits.map(x => x.toString), ", ")})" + case e: DefPrim[_] => s"node ${e.name} = ${emit(e.op)}(${join(e.args.map(x => emit(x)), ", ")})" case e: DefWire => s"wire ${e.name} : ${emitType(e.kind)}" case e: DefRegister => s"reg ${e.name} : ${emitType(e.kind)}, ${e.clock.name}, ${e.reset.name}" case e: DefMemory => s"cmem ${e.name} : ${emitType(e.kind)}[${e.size}], ${e.clock.name}"; diff --git a/src/main/scala/Chisel/FP.scala b/src/main/scala/Chisel/FP.scala index 9309e5e8..2c50795d 100644 --- a/src/main/scala/Chisel/FP.scala +++ b/src/main/scala/Chisel/FP.scala @@ -32,7 +32,6 @@ package Chisel import Chisel._ import DynamicContext._ import ChiselError._ -import Commands.NoLits /// FLO @@ -78,69 +77,55 @@ object FloPrimOp { } import FloPrimOp._ -class Flo(dir: Direction = NO_DIR, val value:Option[Float] = None) extends Element(dir, Width(32)) with Num[Flo] { +sealed abstract class FloBase[T <: Data](dir: Direction, width: Width) extends Element(dir, width) { + protected def unop(op: PrimOp): T = + pushOp(DefPrim(cloneType, op, this.ref)).asInstanceOf[T] + protected def binop(op: PrimOp, other: T): T = + pushOp(DefPrim(cloneType, op, this.ref, other.ref)).asInstanceOf[T] + protected def compop(op: PrimOp, other: T): Bool = + pushOp(DefPrim(Bool(), op, this.ref, other.ref)) + + def toUInt = toBits +} + +class Flo(dir: Direction = NO_DIR, val value:Option[Float] = None) extends FloBase[Flo](dir, Width(32)) with Num[Flo] { type T = Flo; override def floLitValue: Float = value.get def cloneTypeWidth(width: Width): this.type = cloneType - override def fromBits(n: Bits): this.type = { - val d = cloneType - pushCommand(DefPrim(d, d.toType, BitsToFlo, Array(this.ref), NoLits)) - d - } - override def toBits: UInt = { - val d = UInt(dir, 32) - pushCommand(DefPrim(d, d.toType, FloToBits, Array(this.ref), NoLits)) - d - } + override def fromBits(n: Bits): this.type = + pushOp(DefPrim(cloneType, BitsToFlo, this.ref)).asInstanceOf[this.type] + override def toBits: UInt = + pushOp(DefPrim(UInt(width=32), FloToBits, this.ref)) def toType: Kind = FloType(isFlip) def cloneType: this.type = new Flo(dir).asInstanceOf[this.type] - def flatten: IndexedSeq[Bits] = IndexedSeq(toBits) def fromInt(x: Int): Flo = Flo(x.toFloat).asInstanceOf[this.type] - private def flo_unop(op: PrimOp): Flo = { - val d = cloneType - pushCommand(DefPrim(d, d.toType, op, Array(this.ref), NoLits)) - d - } - private def flo_binop(op: PrimOp, other: Flo): Flo = { - val d = cloneType - pushCommand(DefPrim(d, d.toType, op, Array(this.ref, other.ref), NoLits)) - d - } - private def flo_compop(op: PrimOp, other: Flo): Bool = { - val d = new Bool(dir) - pushCommand(DefPrim(d, d.toType, op, Array(this.ref, other.ref), NoLits)) - d - } - - def unary_-() = flo_unop(FloNeg) - def + (b: Flo) = flo_binop(FloAdd, b) - def - (b: Flo) = flo_binop(FloSub, b) - def * (b: Flo) = flo_binop(FloMul, b) - def / (b: Flo) = flo_binop(FloDiv, b) - def % (b: Flo) = flo_binop(FloMod, b) - def ===(b: Flo) = flo_compop(FloEqual, b) - def != (b: Flo) = flo_compop(FloNotEqual, b) - def > (b: Flo) = flo_compop(FloGreater, b) - def < (b: Flo) = flo_compop(FloLess, b) - def <= (b: Flo) = flo_compop(FloLessEqual, b) - def >= (b: Flo) = flo_compop(FloGreaterEqual, b) - def pow (b: Flo) = flo_binop(FloPow, b) - def sin = flo_unop(FloSin) - def cos = flo_unop(FloCos) - def tan = flo_unop(FloTan) - def asin = flo_unop(FloAsin) - def acos = flo_unop(FloAcos) - def atan = flo_unop(FloAtan) - def sqrt = flo_unop(FloSqrt) - def floor = flo_unop(FloFloor) - def ceil = flo_unop(FloCeil) - def round = flo_unop(FloRound) - def log = flo_unop(FloLog) - def toSInt () = SInt(OUTPUT).fromBits(toBits) - def toUInt () = UInt(OUTPUT).fromBits(toBits) + def unary_-() = unop(FloNeg) + def + (b: Flo) = binop(FloAdd, b) + def - (b: Flo) = binop(FloSub, b) + def * (b: Flo) = binop(FloMul, b) + def / (b: Flo) = binop(FloDiv, b) + def % (b: Flo) = binop(FloMod, b) + def ===(b: Flo) = compop(FloEqual, b) + def != (b: Flo) = compop(FloNotEqual, b) + def > (b: Flo) = compop(FloGreater, b) + def < (b: Flo) = compop(FloLess, b) + def <= (b: Flo) = compop(FloLessEqual, b) + def >= (b: Flo) = compop(FloGreaterEqual, b) + def pow (b: Flo) = binop(FloPow, b) + def sin = unop(FloSin) + def cos = unop(FloCos) + def tan = unop(FloTan) + def asin = unop(FloAsin) + def acos = unop(FloAcos) + def atan = unop(FloAtan) + def sqrt = unop(FloSqrt) + def floor = unop(FloFloor) + def ceil = unop(FloCeil) + def round = unop(FloRound) + def log = unop(FloLog) } /// DBL @@ -189,73 +174,44 @@ object DblPrimOp { } import DblPrimOp._ -class Dbl(dir: Direction, val value: Option[Double] = None) extends Element(dir, Width(64)) with Num[Dbl] { - // setIsSigned - - // override def setIsTypeNode = {inputs(0).setIsSigned; super.setIsTypeNode} - +class Dbl(dir: Direction, val value: Option[Double] = None) extends FloBase[Dbl](dir, Width(64)) with Num[Dbl] { type T = Dbl; override def dblLitValue: Double = value.get def cloneTypeWidth(width: Width): this.type = cloneType - override def fromBits(n: Bits): this.type = { - val d = cloneType - pushCommand(DefPrim(d, d.toType, BitsToDbl, Array(this.ref), NoLits)) - d - } - override def toBits: UInt = { - val d = UInt(dir, 64) - pushCommand(DefPrim(d, d.toType, DblToBits, Array(this.ref), NoLits)) - d - } + override def fromBits(n: Bits): this.type = + pushOp(DefPrim(cloneType, BitsToDbl, this.ref)).asInstanceOf[this.type] + override def toBits: UInt = + pushOp(DefPrim(UInt(width=64), DblToBits, this.ref)) def toType: Kind = DblType(isFlip) def cloneType: this.type = new Dbl(dir).asInstanceOf[this.type] - def flatten: IndexedSeq[Bits] = IndexedSeq(toBits) def fromInt(x: Int): this.type = Dbl(x.toDouble).asInstanceOf[this.type] - private def dbl_unop(op: PrimOp): Dbl = { - val d = cloneType - pushCommand(DefPrim(d, d.toType, op, Array(this.ref), NoLits)) - d - } - private def dbl_binop(op: PrimOp, other: Dbl): Dbl = { - val d = cloneType - pushCommand(DefPrim(d, d.toType, op, Array(this.ref, other.ref), NoLits)) - d - } - private def dbl_compop(op: PrimOp, other: Dbl): Bool = { - val d = new Bool(dir) - pushCommand(DefPrim(d, d.toType, op, Array(this.ref, other.ref), NoLits)) - d - } - - def unary_-() = dbl_unop(DblNeg) - def + (b: Dbl) = dbl_binop(DblAdd, b) - def - (b: Dbl) = dbl_binop(DblSub, b) - def * (b: Dbl) = dbl_binop(DblMul, b) - def / (b: Dbl) = dbl_binop(DblDiv, b) - def % (b: Dbl) = dbl_binop(DblMod, b) - def ===(b: Dbl) = dbl_compop(DblEqual, b) - def != (b: Dbl) = dbl_compop(DblNotEqual, b) - def > (b: Dbl) = dbl_compop(DblGreater, b) - def < (b: Dbl) = dbl_compop(DblLess, b) - def <= (b: Dbl) = dbl_compop(DblLessEqual, b) - def >= (b: Dbl) = dbl_compop(DblGreaterEqual, b) - def pow (b: Dbl) = dbl_binop(DblPow, b) - def sin = dbl_unop(DblSin) - def cos = dbl_unop(DblCos) - def tan = dbl_unop(DblTan) - def asin = dbl_unop(DblAsin) - def acos = dbl_unop(DblAcos) - def atan = dbl_unop(DblAtan) - def sqrt = dbl_unop(DblSqrt) - def floor = dbl_unop(DblFloor) - def ceil = dbl_unop(DblCeil) - def round = dbl_unop(DblRound) - def log = dbl_unop(DblLog) - def toSInt () = SInt(OUTPUT).fromBits(toBits) - def toUInt () = UInt(OUTPUT).fromBits(toBits) + def unary_-() = unop(DblNeg) + def + (b: Dbl) = binop(DblAdd, b) + def - (b: Dbl) = binop(DblSub, b) + def * (b: Dbl) = binop(DblMul, b) + def / (b: Dbl) = binop(DblDiv, b) + def % (b: Dbl) = binop(DblMod, b) + def ===(b: Dbl) = compop(DblEqual, b) + def != (b: Dbl) = compop(DblNotEqual, b) + def > (b: Dbl) = compop(DblGreater, b) + def < (b: Dbl) = compop(DblLess, b) + def <= (b: Dbl) = compop(DblLessEqual, b) + def >= (b: Dbl) = compop(DblGreaterEqual, b) + def pow (b: Dbl) = binop(DblPow, b) + def sin = unop(DblSin) + def cos = unop(DblCos) + def tan = unop(DblTan) + def asin = unop(DblAsin) + def acos = unop(DblAcos) + def atan = unop(DblAtan) + def sqrt = unop(DblSqrt) + def floor = unop(DblFloor) + def ceil = unop(DblCeil) + def round = unop(DblRound) + def log = unop(DblLog) } object Sin { |
