aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/PrimOps.scala516
1 files changed, 207 insertions, 309 deletions
diff --git a/src/main/scala/firrtl/PrimOps.scala b/src/main/scala/firrtl/PrimOps.scala
index 60c2082a..dc6dfadb 100644
--- a/src/main/scala/firrtl/PrimOps.scala
+++ b/src/main/scala/firrtl/PrimOps.scala
@@ -110,313 +110,211 @@ object PrimOps extends LazyLogging {
def fromString(op: String): PrimOp = strToPrimOp(op)
// 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))
- }
- val o = e.op
- val a = e.args
- val c = e.consts
- def t1 () = a(0).tpe
- def t2 () = a(1).tpe
- def t3 () = a(2).tpe
- def w1 () = Utils.width_BANG(a(0).tpe)
- def w2 () = Utils.width_BANG(a(1).tpe)
- def w3 () = Utils.width_BANG(a(2).tpe)
- def c1 () = IntWidth(c(0))
- def c2 () = IntWidth(c(1))
- o match {
- case Add => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Sub => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),IntWidth(1)))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Mul => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(PLUS(w1(),w2()))
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
- case (t1:SIntType, t2:UIntType) => SIntType(PLUS(w1(),w2()))
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Div => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(w1())
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),IntWidth(1)))
- case (t1:SIntType, t2:UIntType) => SIntType(w1())
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),IntWidth(1)))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Rem => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(MIN(w1(),w2()))
- case (t1:UIntType, t2:SIntType) => UIntType(MIN(w1(),w2()))
- case (t1:SIntType, t2:UIntType) => SIntType(MIN(w1(),PLUS(w2(),IntWidth(1))))
- case (t1:SIntType, t2:SIntType) => SIntType(MIN(w1(),w2()))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Lt => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Leq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Gt => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Geq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Eq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Neq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Pad => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(MAX(w1(),c1()))
- case (t1:SIntType) => SIntType(MAX(w1(),c1()))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case AsUInt => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(w1())
- case (t1:SIntType) => UIntType(w1())
- case ClockType => UIntType(IntWidth(1))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case AsSInt => {
- val t = (t1()) match {
- case (t1:UIntType) => SIntType(w1())
- case (t1:SIntType) => SIntType(w1())
- case ClockType => SIntType(IntWidth(1))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case AsClock => {
- val t = (t1()) match {
- case (t1:UIntType) => ClockType
- case (t1:SIntType) => ClockType
- case ClockType => ClockType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Shl => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(PLUS(w1(),c1()))
- case (t1:SIntType) => SIntType(PLUS(w1(),c1()))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Shr => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(MAX(MINUS(w1(),c1()),IntWidth(1)))
- case (t1:SIntType) => SIntType(MAX(MINUS(w1(),c1()),IntWidth(1)))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Dshl => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(PLUS(w1(),POW(w2())))
- case (t1:SIntType) => SIntType(PLUS(w1(),POW(w2())))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Dshr => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(w1())
- case (t1:SIntType) => SIntType(w1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Cvt => {
- val t = (t1()) match {
- case (t1:UIntType) => SIntType(PLUS(w1(),IntWidth(1)))
- case (t1:SIntType) => SIntType(w1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Neg => {
- val t = (t1()) match {
- case (t1:UIntType) => SIntType(PLUS(w1(),IntWidth(1)))
- case (t1:SIntType) => SIntType(PLUS(w1(),IntWidth(1)))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Not => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(w1())
- case (t1:SIntType) => UIntType(w1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case And => {
- val t = (t1(),t2()) match {
- case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
- case (t1,t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Or => {
- val t = (t1(),t2()) match {
- case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
- case (t1,t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Xor => {
- val t = (t1(),t2()) match {
- case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
- case (t1,t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Andr => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => Utils.BoolType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Orr => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => Utils.BoolType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Xorr => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => Utils.BoolType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Cat => {
- val t = (t1(),t2()) match {
- case (_:UIntType|_:SIntType,_:UIntType|_:SIntType) => UIntType(PLUS(w1(),w2()))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Bits => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => UIntType(PLUS(MINUS(c1(),c2()),IntWidth(1)))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Head => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => UIntType(c1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Tail => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => UIntType(MINUS(w1(),c1()))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
-
- }
- }
-
+ 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(0).tpe
+ def t2 = e.args(1).tpe
+ def t3 = e.args(2).tpe
+ def w1 = Utils.width_BANG(e.args(0).tpe)
+ def w2 = Utils.width_BANG(e.args(1).tpe)
+ def c1 = IntWidth(e.consts(0))
+ def c2 = IntWidth(e.consts(1))
+ e copy (tpe = (e.op match {
+ case Add => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => UIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case (_: UIntType, _: SIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case (_: SIntType, _: UIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case (_: SIntType, _: SIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case _ => UnknownType
+ }
+ case Sub => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case (_: UIntType, _: SIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case (_: SIntType, _: UIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case (_: SIntType, _: SIntType) => SIntType(PLUS(MAX(w1, w2), IntWidth(1)))
+ case _ => UnknownType
+ }
+ case Mul => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => UIntType(PLUS(w1, w2))
+ case (_: UIntType, _: SIntType) => SIntType(PLUS(w1, w2))
+ case (_: SIntType, _: UIntType) => SIntType(PLUS(w1, w2))
+ case (_: SIntType, _: SIntType) => SIntType(PLUS(w1, w2))
+ case _ => UnknownType
+ }
+ case Div => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => UIntType(w1)
+ case (_: UIntType, _: SIntType) => SIntType(PLUS(w1, IntWidth(1)))
+ case (_: SIntType, _: UIntType) => SIntType(w1)
+ case (_: SIntType, _: SIntType) => SIntType(PLUS(w1, IntWidth(1)))
+ case _ => UnknownType
+ }
+ case Rem => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => UIntType(MIN(w1, w2))
+ case (_: UIntType, _: SIntType) => UIntType(MIN(w1, w2))
+ case (_: SIntType, _: UIntType) => SIntType(MIN(w1, PLUS(w2, IntWidth(1))))
+ case (_: SIntType, _: SIntType) => SIntType(MIN(w1, w2))
+ case _ => UnknownType
+ }
+ case Lt => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => Utils.BoolType
+ case (_: SIntType, _: UIntType) => Utils.BoolType
+ case (_: UIntType, _: SIntType) => Utils.BoolType
+ case (_: SIntType, _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Leq => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => Utils.BoolType
+ case (_: SIntType, _: UIntType) => Utils.BoolType
+ case (_: UIntType, _: SIntType) => Utils.BoolType
+ case (_: SIntType, _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Gt => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => Utils.BoolType
+ case (_: SIntType, _: UIntType) => Utils.BoolType
+ case (_: UIntType, _: SIntType) => Utils.BoolType
+ case (_: SIntType, _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Geq => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => Utils.BoolType
+ case (_: SIntType, _: UIntType) => Utils.BoolType
+ case (_: UIntType, _: SIntType) => Utils.BoolType
+ case (_: SIntType, _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Eq => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => Utils.BoolType
+ case (_: SIntType, _: UIntType) => Utils.BoolType
+ case (_: UIntType, _: SIntType) => Utils.BoolType
+ case (_: SIntType, _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Neq => (t1, t2) match {
+ case (_: UIntType, _: UIntType) => Utils.BoolType
+ case (_: SIntType, _: UIntType) => Utils.BoolType
+ case (_: UIntType, _: SIntType) => Utils.BoolType
+ case (_: SIntType, _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Pad => t1 match {
+ case _: UIntType => UIntType(MAX(w1, c1))
+ case _: SIntType => SIntType(MAX(w1, c1))
+ case _ => UnknownType
+ }
+ case AsUInt => t1 match {
+ case _: UIntType => UIntType(w1)
+ case _: SIntType => UIntType(w1)
+ case ClockType => UIntType(IntWidth(1))
+ case _ => UnknownType
+ }
+ case AsSInt => t1 match {
+ case _: UIntType => SIntType(w1)
+ case _: SIntType => SIntType(w1)
+ case ClockType => SIntType(IntWidth(1))
+ case _ => UnknownType
+ }
+ case AsClock => t1 match {
+ case _: UIntType => ClockType
+ case _: SIntType => ClockType
+ case ClockType => ClockType
+ case _ => UnknownType
+ }
+ case Shl => t1 match {
+ case _: UIntType => UIntType(PLUS(w1,c1))
+ case _: SIntType => SIntType(PLUS(w1,c1))
+ 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 _ => UnknownType
+ }
+ case Dshl => t1 match {
+ case _: UIntType => UIntType(PLUS(w1,POW(w2)))
+ case _: SIntType => SIntType(PLUS(w1,POW(w2)))
+ case _ => UnknownType
+ }
+ case Dshr => t1 match {
+ case _: UIntType => UIntType(w1)
+ case _: SIntType => SIntType(w1)
+ case _ => UnknownType
+ }
+ case Cvt => t1 match {
+ case _: UIntType => SIntType(PLUS(w1,IntWidth(1)))
+ case _: SIntType => SIntType(w1)
+ case _ => UnknownType
+ }
+ case Neg => t1 match {
+ case _: UIntType => SIntType(PLUS(w1,IntWidth(1)))
+ case _: SIntType => SIntType(PLUS(w1,IntWidth(1)))
+ case _ => UnknownType
+ }
+ case Not => t1 match {
+ case _: UIntType => UIntType(w1)
+ case _: SIntType => UIntType(w1)
+ case _ => UnknownType
+ }
+ case And => (t1, t2) match {
+ case (_: SIntType | _: UIntType, _: SIntType | _: UIntType) => UIntType(MAX(w1, w2))
+ case _ => UnknownType
+ }
+ case Or => (t1, t2) match {
+ case (_: SIntType | _: UIntType, _: SIntType | _: UIntType) => UIntType(MAX(w1, w2))
+ case _ => UnknownType
+ }
+ case Xor => (t1, t2) match {
+ case (_: SIntType | _: UIntType, _: SIntType | _: UIntType) => UIntType(MAX(w1, w2))
+ case _ => UnknownType
+ }
+ case Andr => t1 match {
+ case (_: UIntType | _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Orr => t1 match {
+ case (_: UIntType | _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Xorr => t1 match {
+ case (_: UIntType | _: SIntType) => Utils.BoolType
+ case _ => UnknownType
+ }
+ case Cat => (t1, t2) match {
+ case (_: UIntType | _: SIntType, _: UIntType | _: SIntType) => UIntType(PLUS(w1, w2))
+ case (t1, t2) => UnknownType
+ }
+ case Bits => t1 match {
+ case (_: UIntType | _: SIntType) => UIntType(PLUS(MINUS(c1,c2),IntWidth(1)))
+ case _ => UnknownType
+ }
+ case Head => t1 match {
+ case (_: UIntType | _: SIntType) => UIntType(c1)
+ case _ => UnknownType
+ }
+ case Tail => t1 match {
+ case (_: UIntType | _: SIntType) => UIntType(MINUS(w1,c1))
+ case _ => UnknownType
+ }
+ }))
+ }
}