diff options
| author | azidar | 2016-01-30 01:02:48 -0800 |
|---|---|---|
| committer | azidar | 2016-02-09 18:55:26 -0800 |
| commit | f6917276250258091e98a51719b35cf5935ceabf (patch) | |
| tree | b9b3db517d4c69563c4adfca8f07a21e88c3d5d6 /src/main/scala/firrtl/PrimOps.scala | |
| parent | 0181686fe4bdf24f9e22f406c43dbeb98789cb8b (diff) | |
WIP. Finished to working ir, resolve kinds, and infer types
Diffstat (limited to 'src/main/scala/firrtl/PrimOps.scala')
| -rw-r--r-- | src/main/scala/firrtl/PrimOps.scala | 422 |
1 files changed, 329 insertions, 93 deletions
diff --git a/src/main/scala/firrtl/PrimOps.scala b/src/main/scala/firrtl/PrimOps.scala index 4732e756..56d1053c 100644 --- a/src/main/scala/firrtl/PrimOps.scala +++ b/src/main/scala/firrtl/PrimOps.scala @@ -9,38 +9,38 @@ import DebugUtils._ object PrimOps extends LazyLogging { private val mapPrimOp2String = Map[PrimOp, String]( - AddOp -> "add", - SubOp -> "sub", - MulOp -> "mul", - DivOp -> "div", - RemOp -> "rem", - LessOp -> "lt", - LessEqOp -> "leq", - GreaterOp -> "gt", - GreaterEqOp -> "geq", - EqualOp -> "eq", - NEqualOp -> "neq", - PadOp -> "pad", - AsUIntOp -> "asUInt", - AsSIntOp -> "asSInt", - AsClockOp -> "asClock", - ShiftLeftOp -> "shl", - ShiftRightOp -> "shr", - DynShiftLeftOp -> "dshl", - DynShiftRightOp -> "dshr", - ConvertOp -> "cvt", - NegOp -> "neg", - BitNotOp -> "not", - BitAndOp -> "and", - BitOrOp -> "or", - BitXorOp -> "xor", - BitAndReduceOp -> "andr", - BitOrReduceOp -> "orr", - BitXorReduceOp -> "xorr", - ConcatOp -> "cat", - BitsSelectOp -> "bits", - HeadOp -> "head", - TailOp -> "tail" + ADD_OP -> "add", + SUB_OP -> "sub", + MUL_OP -> "mul", + DIV_OP -> "div", + REM_OP -> "rem", + LESS_OP -> "lt", + LESS_EQ_OP -> "leq", + GREATER_OP -> "gt", + GREATER_EQ_OP -> "geq", + EQUAL_OP -> "eq", + NEQUAL_OP -> "neq", + PAD_OP -> "pad", + AS_UINT_OP -> "asUInt", + AS_SINT_OP -> "asSInt", + AS_CLOCK_OP -> "asClock", + SHIFT_LEFT_OP -> "shl", + SHIFT_RIGHT_OP -> "shr", + DYN_SHIFT_LEFT_OP -> "dshl", + DYN_SHIFT_RIGHT_OP -> "dshr", + NEG_OP -> "neg", + CONVERT_OP -> "cvt", + NOT_OP -> "not", + AND_OP -> "and", + OR_OP -> "or", + XOR_OP -> "xor", + AND_REDUCE_OP -> "andr", + OR_REDUCE_OP -> "orr", + XOR_REDUCE_OP -> "xorr", + CONCAT_OP -> "cat", + BITS_SELECT_OP -> "bits", + HEAD_OP -> "head", + TAIL_OP -> "tail" ) private val mapString2PrimOp = mapPrimOp2String.map(_.swap) def fromString(op: String): PrimOp = mapString2PrimOp(op) @@ -50,67 +50,303 @@ object PrimOps extends LazyLogging { } // Borrowed from Stanza implementation - def lowerAndTypePrimOp(e: DoPrim): DoPrim = { - def uAnd(op1: Expression, op2: Expression): Type = { - (op1.getType, op2.getType) match { - case (t1: UIntType, t2: UIntType) => UIntType(UnknownWidth) - case (t1: SIntType, t2) => SIntType(UnknownWidth) - case (t1, t2: SIntType) => SIntType(UnknownWidth) - case _ => UnknownType() - } - } - def ofType(op: Expression): Type = { - op.getType match { - case t: UIntType => UIntType(UnknownWidth) - case t: SIntType => SIntType(UnknownWidth) - case _ => UnknownType() - } - } + def set_primop_type (e:DoPrim) : DoPrim = { + //println-all(["Inferencing primop type: " e]) + def PLUS (w1:Width,w2:Width) : Width = PlusWidth(w1,w2) + def MAX (w1:Width,w2:Width) : Width = MaxWidth(Seq(w1,w2)) + def MINUS (w1:Width,w2:Width) : Width = MinusWidth(w1,w2) + def POW (w1:Width) : Width = ExpWidth(w1) + def MIN (w1:Width,w2:Width) : Width = MinWidth(Seq(w1,w2)) + val o = e.op + val a = e.args + val c = e.consts + def t1 () = tpe(a(0)) + def t2 () = tpe(a(1)) + def t3 () = tpe(a(2)) + def w1 () = widthBANG(tpe(a(0))) + def w2 () = widthBANG(tpe(a(1))) + def w3 () = widthBANG(tpe(a(2))) + def c1 () = IntWidth(c(0)) + def c2 () = IntWidth(c(1)) + o match { + case ADD_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => UIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case SUB_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE)) + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case MUL_OP => { + 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_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => UIntType(w1()) + case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),ONE)) + case (t1:SIntType, t2:UIntType) => SIntType(w1()) + case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),ONE)) + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case REM_OP => { + 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(),ONE))) + case (t1:SIntType, t2:SIntType) => SIntType(MIN(w1(),w2())) + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case LESS_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => BoolType() + case (t1:SIntType, t2:UIntType) => BoolType() + case (t1:UIntType, t2:SIntType) => BoolType() + case (t1:SIntType, t2:SIntType) => BoolType() + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case LESS_EQ_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => BoolType() + case (t1:SIntType, t2:UIntType) => BoolType() + case (t1:UIntType, t2:SIntType) => BoolType() + case (t1:SIntType, t2:SIntType) => BoolType() + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case GREATER_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => BoolType() + case (t1:SIntType, t2:UIntType) => BoolType() + case (t1:UIntType, t2:SIntType) => BoolType() + case (t1:SIntType, t2:SIntType) => BoolType() + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case GREATER_EQ_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => BoolType() + case (t1:SIntType, t2:UIntType) => BoolType() + case (t1:UIntType, t2:SIntType) => BoolType() + case (t1:SIntType, t2:SIntType) => BoolType() + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case EQUAL_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => BoolType() + case (t1:SIntType, t2:UIntType) => BoolType() + case (t1:UIntType, t2:SIntType) => BoolType() + case (t1:SIntType, t2:SIntType) => BoolType() + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case NEQUAL_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => BoolType() + case (t1:SIntType, t2:UIntType) => BoolType() + case (t1:UIntType, t2:SIntType) => BoolType() + case (t1:SIntType, t2:SIntType) => BoolType() + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case PAD_OP => { + 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 AS_UINT_OP => { + val t = (t1()) match { + case (t1:UIntType) => UIntType(w1()) + case (t1:SIntType) => UIntType(w1()) + case (t1:ClockType) => UIntType(ONE) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case AS_SINT_OP => { + val t = (t1()) match { + case (t1:UIntType) => SIntType(w1()) + case (t1:SIntType) => SIntType(w1()) + case (t1:ClockType) => SIntType(ONE) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case AS_CLOCK_OP => { + val t = (t1()) match { + case (t1:UIntType) => ClockType() + case (t1:SIntType) => ClockType() + case (t1:ClockType) => ClockType() + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case SHIFT_LEFT_OP => { + 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 SHIFT_RIGHT_OP => { + val t = (t1()) match { + case (t1:UIntType) => UIntType(MINUS(w1(),c1())) + case (t1:SIntType) => SIntType(MINUS(w1(),c1())) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case DYN_SHIFT_LEFT_OP => { + 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 DYN_SHIFT_RIGHT_OP => { + val t = (t1()) match { + case (t1:UIntType) => UIntType(w1()) + case (t1:SIntType) => SIntType(w1()) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case CONVERT_OP => { + val t = (t1()) match { + case (t1:UIntType) => SIntType(PLUS(w1(),ONE)) + case (t1:SIntType) => SIntType(w1()) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case NEG_OP => { + val t = (t1()) match { + case (t1:UIntType) => SIntType(PLUS(w1(),ONE)) + case (t1:SIntType) => SIntType(PLUS(w1(),ONE)) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case NOT_OP => { + val t = (t1()) match { + case (t1:UIntType) => UIntType(w1()) + case (t1:SIntType) => UIntType(w1()) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case AND_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:SIntType) => UIntType(MAX(w1(),w2())) + case (t1,t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case OR_OP => { + val t = (t1(),t2()) match { + case (t1:SIntType, t2:SIntType) => UIntType(MAX(w1(),w2())) + case (t1,t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case XOR_OP => { + val t = (t1(),t2()) match { + case (t1:UIntType, t2:UIntType) => UIntType(MAX(w1(),w2())) + case (t1:SIntType, t2:UIntType) => UIntType(MAX(w1(),w2())) + case (t1:UIntType, t2:SIntType) => UIntType(MAX(w1(),w2())) + case (t1:SIntType, t2:SIntType) => UIntType(MAX(w1(),w2())) + case (t1,t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case AND_REDUCE_OP => { + val t = (t1()) match { + case (t1:UIntType) => BoolType() + case (t1:SIntType) => BoolType() + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case OR_REDUCE_OP => { + val t = (t1()) match { + case (t1:UIntType) => BoolType() + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case XOR_REDUCE_OP => { + val t = (t1()) match { + case (t1:SIntType) => BoolType() + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case CONCAT_OP => { + val t = (t1(),t2()) match { + case (t1:SIntType, t2:SIntType) => UIntType(PLUS(w1(),w2())) + case (t1, t2) => UnknownType() + } + DoPrim(o,a,c,t) + } + case BITS_SELECT_OP => { + val t = (t1()) match { + case (t1:UIntType) => UIntType(PLUS(MINUS(c1(),c2()),ONE)) + case (t1:SIntType) => UIntType(PLUS(MINUS(c1(),c2()),ONE)) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case HEAD_OP => { + val t = (t1()) match { + case (t1:UIntType) => UIntType(c1()) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } + case TAIL_OP => { + val t = (t1()) match { + case (t1:SIntType) => UIntType(MINUS(w1(),c1())) + case (t1) => UnknownType() + } + DoPrim(o,a,c,t) + } - logger.debug(s"lowerAndTypePrimOp on ${e.op.getClass.getSimpleName}") - // TODO fix this - val tpe = UIntType(UnknownWidth) - //val tpe = e.op match { - // case Add => uAnd(e.args(0), e.args(1)) - // case Sub => SIntType(UnknownWidth) - // case Addw => uAnd(e.args(0), e.args(1)) - // case Subw => uAnd(e.args(0), e.args(1)) - // case Mul => uAnd(e.args(0), e.args(1)) - // case Div => uAnd(e.args(0), e.args(1)) - // case Mod => ofType(e.args(0)) - // case Quo => uAnd(e.args(0), e.args(1)) - // case Rem => ofType(e.args(1)) - // case Lt => UIntType(UnknownWidth) - // case Leq => UIntType(UnknownWidth) - // case Gt => UIntType(UnknownWidth) - // case Geq => UIntType(UnknownWidth) - // case Eq => UIntType(UnknownWidth) - // case Neq => UIntType(UnknownWidth) - // case Eqv => UIntType(UnknownWidth) - // case Neqv => UIntType(UnknownWidth) - // case Mux => ofType(e.args(1)) - // case Pad => ofType(e.args(0)) - // case AsUInt => UIntType(UnknownWidth) - // case AsSInt => SIntType(UnknownWidth) - // case Shl => ofType(e.args(0)) - // case Shr => ofType(e.args(0)) - // case Dshl => ofType(e.args(0)) - // case Dshr => ofType(e.args(0)) - // case Cvt => SIntType(UnknownWidth) - // case Neg => SIntType(UnknownWidth) - // case Not => ofType(e.args(0)) - // case And => ofType(e.args(0)) - // case Or => ofType(e.args(0)) - // case Xor => ofType(e.args(0)) - // case Andr => UIntType(UnknownWidth) - // case Orr => UIntType(UnknownWidth) - // case Xorr => UIntType(UnknownWidth) - // case Cat => UIntType(UnknownWidth) - // case Bit => UIntType(UnknownWidth) - // case Bits => UIntType(UnknownWidth) - // case _ => ??? - //} - DoPrim(e.op, e.args, e.consts, tpe) - } + } + } } |
