diff options
| author | Adam Izraelevitz | 2016-10-17 15:10:12 -0700 |
|---|---|---|
| committer | GitHub | 2016-10-17 15:10:12 -0700 |
| commit | 7d08b9a1486fef0459481f6e542464a29fbe1db5 (patch) | |
| tree | e8b2289ac5cbecbd59d58cab8bd503287818ec5d /src/main/scala/firrtl/PrimOps.scala | |
| parent | 2848d87721df110d0425114283cb5fa7e6c2ee03 (diff) | |
Add fixed point type (#322)
* WIP: Adding FixedType to Firrtl proper
Got simple example running through width inference
Checks should be ok
Need to look into FixedLiteral more
* Added simple test for fixed types
* Added asFixedPoint to primops
* Added tail case for FixedType
* Added ConvertFixedToSInt.scala
Added pass to MiddleToLowerFirrtl transform
* Replace AsFixedType with AsSInt in fixed removal
* Bugfix: constant from asFixed not deleted
* Added unit test for bulk connect
* Fixed partial connect bug #241
* Fixed missing case for FixedPoint in legalizeConnect
* Add FixedMathSpec that demonstrates some problems with FixedPointMath
* Fixed test and ConvertToSInt to pass.
Negative binary points not easily supported, needs much more time to
implement.
* Refactored checking neg widths
Make checking for negative binary points easier
* Added tests for inferring many FixedType ops
shl, shr, cat, bits, head, tail, setbp, shiftbp
* Handle bpshl, bpshr, bpset in ConvertFixedToSInt
Changed name from shiftbp -> bpshl, bpshr
Change name from setbp -> bpset
Added more tests
* Added set binary point test that fails
* Added simple test for zero binary point
* gitignore fixes for antlr intermediate dir and intellij dir
* removed unused imports
retool the fixed point with zero binary point test
* simplified example of inability to set binary point to zero
* Temporary fix for zero-width binary point
This fix allows for all widths to be zero, but since this is a feature I
am working on next, I'm not going to bother with a more stringent check.
* change version for dsp tools
* Removed extra temporary file
* Fixed merge bug
* Fixed another merge bug
* Removed commented out/unrelated files
* Removed snake case
Diffstat (limited to 'src/main/scala/firrtl/PrimOps.scala')
| -rw-r--r-- | src/main/scala/firrtl/PrimOps.scala | 99 |
1 files changed, 75 insertions, 24 deletions
diff --git a/src/main/scala/firrtl/PrimOps.scala b/src/main/scala/firrtl/PrimOps.scala index e3dd11c0..ea265369 100644 --- a/src/main/scala/firrtl/PrimOps.scala +++ b/src/main/scala/firrtl/PrimOps.scala @@ -28,7 +28,7 @@ MODIFICATIONS. package firrtl import firrtl.ir._ -import firrtl.Utils.{max, min, pow_minus_one} +import firrtl.Utils.{min, max, pow_minus_one} import com.typesafe.scalalogging.LazyLogging @@ -98,10 +98,18 @@ object PrimOps extends LazyLogging { case object Head extends PrimOp { override def toString = "head" } /** Tail */ case object Tail extends PrimOp { override def toString = "tail" } + /** Interpret as Fixed Point **/ + case object AsFixedPoint extends PrimOp { override def toString = "asFixedPoint" } + /** Shift Binary Point Left **/ + case object BPShl extends PrimOp { override def toString = "bpshl" } + /** Shift Binary Point Right **/ + case object BPShr extends PrimOp { override def toString = "bpshr" } + /** Set Binary Point **/ + case object BPSet extends PrimOp { override def toString = "bpset" } private lazy val builtinPrimOps: Seq[PrimOp] = Seq(Add, Sub, Mul, Div, Rem, Lt, Leq, Gt, Geq, Eq, Neq, Pad, AsUInt, AsSInt, AsClock, Shl, Shr, - Dshl, Dshr, Neg, Cvt, Not, And, Or, Xor, Andr, Orr, Xorr, Cat, Bits, Head, Tail) + Dshl, Dshr, Neg, Cvt, Not, And, Or, Xor, Andr, Orr, Xorr, Cat, Bits, Head, Tail, AsFixedPoint, BPShl, BPShr, BPSet) private lazy val strToPrimOp: Map[String, PrimOp] = builtinPrimOps.map { case op : PrimOp=> op.toString -> op }.toMap /** Seq of String representations of [[ir.PrimOp]]s */ @@ -109,34 +117,38 @@ object PrimOps extends LazyLogging { /** Gets the corresponding [[ir.PrimOp]] from its String representation */ def fromString(op: String): PrimOp = strToPrimOp(op) + // Width Constraint Functions + def PLUS (w1:Width, w2:Width) : Width = (w1, w2) match { + case (IntWidth(i), IntWidth(j)) => IntWidth(i + j) + case _ => PlusWidth(w1, w2) + } + def MAX (w1:Width, w2:Width) : Width = (w1, w2) match { + case (IntWidth(i), IntWidth(j)) => IntWidth(max(i,j)) + case _ => MaxWidth(Seq(w1, w2)) + } + def MINUS (w1:Width, w2:Width) : Width = (w1, w2) match { + case (IntWidth(i), IntWidth(j)) => IntWidth(i - j) + case _ => MinusWidth(w1, w2) + } + def POW (w1:Width) : Width = w1 match { + case IntWidth(i) => IntWidth(pow_minus_one(BigInt(2), i)) + case _ => ExpWidth(w1) + } + def MIN (w1:Width, w2:Width) : Width = (w1, w2) match { + case (IntWidth(i), IntWidth(j)) => IntWidth(min(i,j)) + case _ => MinWidth(Seq(w1, w2)) + } + // Borrowed from Stanza implementation def set_primop_type (e:DoPrim) : DoPrim = { //println-all(["Inferencing primop type: " e]) - def PLUS (w1:Width, w2:Width) : Width = (w1, w2) match { - case (IntWidth(i), IntWidth(j)) => IntWidth(i + j) - case _ => PlusWidth(w1, w2) - } - def MAX (w1:Width, w2:Width) : Width = (w1, w2) match { - case (IntWidth(i), IntWidth(j)) => IntWidth(max(i,j)) - case _ => MaxWidth(Seq(w1, w2)) - } - def MINUS (w1:Width, w2:Width) : Width = (w1, w2) match { - case (IntWidth(i), IntWidth(j)) => IntWidth(i - j) - case _ => MinusWidth(w1, w2) - } - def POW (w1:Width) : Width = w1 match { - case IntWidth(i) => IntWidth(pow_minus_one(BigInt(2), i)) - case _ => ExpWidth(w1) - } - def MIN (w1:Width, w2:Width) : Width = (w1, w2) match { - case (IntWidth(i), IntWidth(j)) => IntWidth(min(i,j)) - case _ => MinWidth(Seq(w1, w2)) - } def t1 = e.args.head.tpe def t2 = e.args(1).tpe def t3 = e.args(2).tpe def w1 = passes.getWidth(e.args.head.tpe) def w2 = passes.getWidth(e.args(1).tpe) + def p1 = t1 match { case FixedType(w, p) => p } //Intentional + def p2 = t2 match { case FixedType(w, p) => p } //Intentional def c1 = IntWidth(e.consts.head) def c2 = IntWidth(e.consts(1)) e copy (tpe = e.op match { @@ -145,6 +157,7 @@ object PrimOps extends LazyLogging { case (_: UIntType, _: SIntType) => SIntType(PLUS(MAX(w1, MINUS(w2, IntWidth(1))), IntWidth(2))) case (_: SIntType, _: UIntType) => SIntType(PLUS(MAX(w2, MINUS(w1, IntWidth(1))), IntWidth(2))) case (_: SIntType, _: SIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1))) + case (_: FixedType, _: FixedType) => FixedType(PLUS(PLUS(MAX(p1, p2), MAX(MINUS(w1, p1), MINUS(w2, p2))), IntWidth(1)), MAX(p1, p2)) case _ => UnknownType } case Sub => (t1, t2) match { @@ -152,6 +165,7 @@ object PrimOps extends LazyLogging { case (_: UIntType, _: SIntType) => SIntType(MAX(PLUS(w2, IntWidth(1)), PLUS(w1, IntWidth(2)))) case (_: SIntType, _: UIntType) => SIntType(MAX(PLUS(w1, IntWidth(1)), PLUS(w2, IntWidth(2)))) case (_: SIntType, _: SIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1))) + case (_: FixedType, _: FixedType) => FixedType(PLUS(PLUS(MAX(p1, p2),MAX(MINUS(w1, p1), MINUS(w2, p2))),IntWidth(1)), MAX(p1, p2)) case _ => UnknownType } case Mul => (t1, t2) match { @@ -159,6 +173,7 @@ object PrimOps extends LazyLogging { case (_: UIntType, _: SIntType) => SIntType(PLUS(w1, w2)) case (_: SIntType, _: UIntType) => SIntType(PLUS(w1, w2)) case (_: SIntType, _: SIntType) => SIntType(PLUS(w1, w2)) + case (_: FixedType, _: FixedType) => FixedType(PLUS(w1, w2), PLUS(p1, p2)) case _ => UnknownType } case Div => (t1, t2) match { @@ -180,6 +195,7 @@ object PrimOps extends LazyLogging { case (_: SIntType, _: UIntType) => Utils.BoolType case (_: UIntType, _: SIntType) => Utils.BoolType case (_: SIntType, _: SIntType) => Utils.BoolType + case (_: FixedType, _: FixedType) => Utils.BoolType case _ => UnknownType } case Leq => (t1, t2) match { @@ -187,6 +203,7 @@ object PrimOps extends LazyLogging { case (_: SIntType, _: UIntType) => Utils.BoolType case (_: UIntType, _: SIntType) => Utils.BoolType case (_: SIntType, _: SIntType) => Utils.BoolType + case (_: FixedType, _: FixedType) => Utils.BoolType case _ => UnknownType } case Gt => (t1, t2) match { @@ -194,6 +211,7 @@ object PrimOps extends LazyLogging { case (_: SIntType, _: UIntType) => Utils.BoolType case (_: UIntType, _: SIntType) => Utils.BoolType case (_: SIntType, _: SIntType) => Utils.BoolType + case (_: FixedType, _: FixedType) => Utils.BoolType case _ => UnknownType } case Geq => (t1, t2) match { @@ -201,6 +219,7 @@ object PrimOps extends LazyLogging { case (_: SIntType, _: UIntType) => Utils.BoolType case (_: UIntType, _: SIntType) => Utils.BoolType case (_: SIntType, _: SIntType) => Utils.BoolType + case (_: FixedType, _: FixedType) => Utils.BoolType case _ => UnknownType } case Eq => (t1, t2) match { @@ -208,6 +227,7 @@ object PrimOps extends LazyLogging { case (_: SIntType, _: UIntType) => Utils.BoolType case (_: UIntType, _: SIntType) => Utils.BoolType case (_: SIntType, _: SIntType) => Utils.BoolType + case (_: FixedType, _: FixedType) => Utils.BoolType case _ => UnknownType } case Neq => (t1, t2) match { @@ -215,16 +235,19 @@ object PrimOps extends LazyLogging { case (_: SIntType, _: UIntType) => Utils.BoolType case (_: UIntType, _: SIntType) => Utils.BoolType case (_: SIntType, _: SIntType) => Utils.BoolType + case (_: FixedType, _: FixedType) => Utils.BoolType case _ => UnknownType } case Pad => t1 match { case _: UIntType => UIntType(MAX(w1, c1)) case _: SIntType => SIntType(MAX(w1, c1)) + case _: FixedType => FixedType(MAX(w1, c1), p1) case _ => UnknownType } case AsUInt => t1 match { case _: UIntType => UIntType(w1) case _: SIntType => UIntType(w1) + case _: FixedType => UIntType(w1) case ClockType => UIntType(IntWidth(1)) case AnalogType(w) => UIntType(w1) case _ => UnknownType @@ -232,10 +255,19 @@ object PrimOps extends LazyLogging { case AsSInt => t1 match { case _: UIntType => SIntType(w1) case _: SIntType => SIntType(w1) + case _: FixedType => SIntType(w1) case ClockType => SIntType(IntWidth(1)) case _: AnalogType => SIntType(w1) case _ => UnknownType } + case AsFixedPoint => t1 match { + case _: UIntType => FixedType(w1, c1) + case _: SIntType => FixedType(w1, c1) + case _: FixedType => FixedType(w1, c1) + case ClockType => FixedType(IntWidth(1), c1) + case _: AnalogType => FixedType(w1, c1) + case _ => UnknownType + } case AsClock => t1 match { case _: UIntType => ClockType case _: SIntType => ClockType @@ -246,21 +278,25 @@ object PrimOps extends LazyLogging { case Shl => t1 match { case _: UIntType => UIntType(PLUS(w1, c1)) case _: SIntType => SIntType(PLUS(w1, c1)) + case _: FixedType => FixedType(PLUS(w1,c1), p1) case _ => UnknownType } case Shr => t1 match { case _: UIntType => UIntType(MAX(MINUS(w1, c1), IntWidth(1))) case _: SIntType => SIntType(MAX(MINUS(w1, c1), IntWidth(1))) + case _: FixedType => FixedType(MAX(MAX(MINUS(w1,c1), IntWidth(1)), p1), p1) case _ => UnknownType } case Dshl => t1 match { case _: UIntType => UIntType(PLUS(w1, POW(w2))) case _: SIntType => SIntType(PLUS(w1, POW(w2))) + case _: FixedType => FixedType(PLUS(w1, POW(w2)), p1) case _ => UnknownType } case Dshr => t1 match { case _: UIntType => UIntType(w1) case _: SIntType => SIntType(w1) + case _: FixedType => FixedType(w1, p1) case _ => UnknownType } case Cvt => t1 match { @@ -304,18 +340,33 @@ object PrimOps extends LazyLogging { } case Cat => (t1, t2) match { case (_: UIntType | _: SIntType, _: UIntType | _: SIntType) => UIntType(PLUS(w1, w2)) + case (_: FixedType, _: UIntType| _: SIntType) => FixedType(PLUS(w1, w2), PLUS(p1, w2)) + case (_: UIntType | _: SIntType, _: FixedType) => FixedType(PLUS(w1, w2), p1) case (t1, t2) => UnknownType } case Bits => t1 match { case (_: UIntType | _: SIntType) => UIntType(PLUS(MINUS(c1, c2), IntWidth(1))) + case _: FixedType => UIntType(PLUS(MINUS(c1, c2), IntWidth(1))) case _ => UnknownType } case Head => t1 match { - case (_: UIntType | _: SIntType) => UIntType(c1) + case (_: UIntType | _: SIntType | _: FixedType) => UIntType(c1) case _ => UnknownType } case Tail => t1 match { - case (_: UIntType | _: SIntType) => UIntType(MINUS(w1, c1)) + case (_: UIntType | _: SIntType | _: FixedType) => UIntType(MINUS(w1, c1)) + case _ => UnknownType + } + case BPShl => t1 match { + case _: FixedType => FixedType(PLUS(w1,c1), PLUS(p1, c1)) + case _ => UnknownType + } + case BPShr => t1 match { + case _: FixedType => FixedType(MINUS(w1,c1), MINUS(p1, c1)) + case _ => UnknownType + } + case BPSet => t1 match { + case _: FixedType => FixedType(PLUS(c1, MINUS(w1, p1)), c1) case _ => UnknownType } }) |
