aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/PrimOps.scala
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-10-17 15:10:12 -0700
committerGitHub2016-10-17 15:10:12 -0700
commit7d08b9a1486fef0459481f6e542464a29fbe1db5 (patch)
treee8b2289ac5cbecbd59d58cab8bd503287818ec5d /src/main/scala/firrtl/PrimOps.scala
parent2848d87721df110d0425114283cb5fa7e6c2ee03 (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.scala99
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
}
})