Skip to content

Commit

Permalink
wow something kinda works
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles Sherk committed Aug 2, 2021
1 parent e141095 commit 9a5f533
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 31 deletions.
5 changes: 3 additions & 2 deletions src/main/scala/pipedsl/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class Parser extends RegexParsers with PackratParsers {
val e = EInt(n, base, if (bits.isDefined) bits.get else log2(n))
e.typ = bits match {
case Some(b) => Some(TSizedInt(TBitWidthLen(b), SignFactory.ofBool(!isUnsigned)))
case None => None
case None if isUnsigned => Some(TSizedInt(TBitWidthLen(e.bits), TUnsigned()))
case _ => None
}
// e.typ = Some(TSizedInt(TBitWidthLen(e.bits), unsigned = isUnsigned))
e
Expand Down Expand Up @@ -264,7 +265,7 @@ class Parser extends RegexParsers with PackratParsers {
seqCmd
}

lazy val sizedInt: P[Type] = "int" ~> angular(posint) ^^ { bits => TSizedInt(TBitWidthLen(bits), TUnsigned() /*unsigned = false*/) } |
lazy val sizedInt: P[Type] = "int" ~> angular(posint) ^^ { bits => TSizedInt(TBitWidthLen(bits), TSigned() /*unsigned = false*/) } |
"uint" ~> angular(posint) ^^ { bits => TSizedInt(TBitWidthLen(bits), TUnsigned() /*unsigned = true*/) }

lazy val latency: P[Latency.Latency] =
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/common/DAGSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,13 @@ object DAGSyntax {
val defaultNum = conds.size
val condVar = EVar(Id("__cond" + n.v))
val intSize = log2(defaultNum)
condVar.typ = Some(TSizedInt(TBitWidthLen(intSize), sign = true))
condVar.typ = Some(TSizedInt(TBitWidthLen(intSize), TUnsigned()))
condVar.id.typ = condVar.typ
var eTernary = ETernary(conds(defaultNum - 1), EInt(defaultNum - 1, bits = intSize), EInt(defaultNum, bits = intSize))
for(i <- defaultNum-2 to 0 by -1 ) {
eTernary = ETernary(conds(i), EInt(i, bits = intSize), eTernary.copy())
}
this.addCmd(CAssign(condVar, eTernary, Some(TSizedInt(TBitWidthLen(intSize), sign = true))))
this.addCmd(CAssign(condVar, eTernary, Some(TSizedInt(TBitWidthLen(intSize), TUnsigned()))))
for (i <- 0 until defaultNum) {
this.addEdgeTo(condStages(i).head, condSend = Some (EBinop(EqOp("=="), condVar, EInt(i, bits = intSize))))
condStages(i).last.addEdgeTo(joinStage, condRecv = Some (EBinop(EqOp("=="), condVar, EInt(i, bits = intSize))))
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/pipedsl/common/Errors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,6 @@ object Errors {
)

case class UnificationError(t1: Type, t2: Type) extends RuntimeException(
s"Unable to unify type $t1 and type $t2"
withPos(s"Unable to unify type $t1 and type $t2", t1.pos)
)
}
2 changes: 1 addition & 1 deletion src/main/scala/pipedsl/common/PrettyPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class PrettyPrinter(output: Option[File]) {

def printType(t: Type): Unit = pline(printTypeToString(t))
def printTypeToString(t: Type): String = t match {
case TSizedInt(len, unsigned) => (if (!unsigned) "s" else "") + "int<" + len.toString + ">"
case TSizedInt(len, sign) => (if (sign.signed()) "s" else "") + "int<" + len.toString + ">"
case TVoid() => "void"
case TBool() => "bool"
case TFun(args, ret) => "(" + args.map(a => printTypeToString(a)).mkString(",") + ") -> " + printTypeToString(ret)
Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/pipedsl/common/Syntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ object Syntax {
case TBitWidthLen(len) => len.toString
case TBitWidthMax(b1, b2) => "max(" + b1 + ", " + b2 + ")"
case TBitWidthVar(name) => "bitVar(" + name + ")"

case TSigned() => "signed"
case TUnsigned() => "unsigned"
case TSignVar(name) => "sign(" + name + ")"
}
}
// Types that can be upcast to Ints
Expand All @@ -115,10 +117,12 @@ object Syntax {
{
case TSigned() => true
case TUnsigned() => false
case _ => false
}
def unsigned() :Boolean = this match {
case TSigned() => false
case TUnsigned() => true
case _ => false
}
}
object SignFactory
Expand Down
95 changes: 95 additions & 0 deletions src/main/scala/pipedsl/common/Utilities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import pipedsl.common.DAGSyntax.PStage
import pipedsl.common.Errors.UnexpectedCommand
import pipedsl.common.Syntax._

import scala.annotation.tailrec


object Utilities {

Expand Down Expand Up @@ -305,6 +307,99 @@ object Utilities {
}
}


def opt_func[A, B](f :A => B) : Option[A] => Option[B] =
{
case Some(value) => Some(f(value))
case None => None
}

private def typeMapExpr(e :Expr, f_opt : Option[Type] => Option[Type]) : Unit =
{
println(s"setting ${e.typ} to ${f_opt(e.typ)}")
e.typ = f_opt(e.typ)
e match
{
case EIsValid(ex) => typeMapExpr(ex, f_opt)
case EFromMaybe(ex) => typeMapExpr(ex, f_opt)
case EToMaybe(ex) => typeMapExpr(ex, f_opt)
case EUop(_, ex) => typeMapExpr(ex, f_opt)
case EBinop(_, e1, e2) => typeMapExpr(e1, f_opt); typeMapExpr(e2, f_opt)
case ERecAccess(rec, fieldName) => typeMapId(fieldName, f_opt); typeMapExpr(rec, f_opt);
case ERecLiteral(fields) =>
fields.foreach(idex => {typeMapId(idex._1, f_opt); typeMapExpr(idex._2, f_opt)})
case EMemAccess(mem, index, wmask) =>
typeMapId(mem, f_opt); typeMapExpr(index, f_opt)
wmask.fold(())(typeMapExpr(_, f_opt))
case EBitExtract(num, _, _) => typeMapExpr(num, f_opt)
case ETernary(cond, tval, fval) =>
typeMapExpr(cond, f_opt); typeMapExpr(tval, f_opt); typeMapExpr(fval, f_opt)
case EApp(func, args) =>
typeMapId(func, f_opt); args.foreach(typeMapExpr(_, f_opt))
case ECall(mod, args) =>
typeMapId(mod, f_opt); args.foreach(typeMapExpr(_, f_opt))
case EVar(id) => typeMapId(id, f_opt)
case ECast(_, exp) => typeMapExpr(exp, f_opt)
case expr: CirExpr => expr match
{
case CirLock(mem, _, _) => typeMapId(mem, f_opt)
case CirNew(mod, mods) => typeMapId(mod, f_opt)
mods.foreach((i: Id) => typeMapId(i, f_opt))
case CirCall(mod, args) => typeMapId(mod, f_opt)
args.foreach(typeMapExpr(_, f_opt))
case _ => ()
}
case _ => ()
}
}
private def typeMapCmd(c :Command, f_opt :Option[Type] => Option[Type]) :Unit = c match
{
case CSeq(c1, c2) => typeMapCmd(c1, f_opt); typeMapCmd(c2, f_opt)
case CTBar(c1, c2) => typeMapCmd(c1, f_opt); typeMapCmd(c2, f_opt)
case CIf(cond, cons, alt) => typeMapExpr(cond, f_opt); typeMapCmd(cons, f_opt); typeMapCmd(alt, f_opt)
case CAssign(lhs, rhs, _) => typeMapExpr(lhs, f_opt); typeMapExpr(rhs, f_opt)
case CRecv(lhs, rhs, _) => typeMapExpr(lhs, f_opt); typeMapExpr(rhs, f_opt)
case CSpecCall(handle, pipe, args) =>
typeMapExpr(handle, f_opt); typeMapId(pipe, f_opt); args.foreach(typeMapExpr(_, f_opt))
case CVerify(handle, args, preds) =>
typeMapExpr(handle, f_opt); args.foreach(typeMapExpr(_, f_opt)); preds.foreach(typeMapExpr(_, f_opt))
case CInvalidate(handle) => typeMapExpr(handle, f_opt)
case CPrint(args) => args.foreach(typeMapExpr(_, f_opt))
case COutput(exp) => typeMapExpr(exp, f_opt)
case CReturn(exp) => typeMapExpr(exp, f_opt)
case CExpr(exp) => typeMapExpr(exp, f_opt)
case CLockStart(mod) => typeMapId(mod, f_opt)
case CLockEnd(mod) => typeMapId(mod, f_opt)
case CLockOp(mem, _, _) =>
typeMapId(mem.id, f_opt);
mem.evar match
{case Some(value) => typeMapExpr(value, f_opt)
case None => ()}
case CSplit(cases, default) =>
cases.foreach(cs => {typeMapExpr(cs.cond, f_opt); typeMapCmd(cs.body, f_opt)})
typeMapCmd(default, f_opt)
case _ => ()
}

private def typeMapId(i: Id, f_opt: Option[Type] => Option[Type]):Unit =
{
i.typ = f_opt(i.typ)
}



def typeMapFunc(fun :FuncDef, f_opt :Option[Type] => Option[Type]) :Unit = typeMapCmd(fun.body, f_opt)
def typeMapModule(mod :ModuleDef, f_opt :Option[Type] => Option[Type]) :Unit = typeMapCmd(mod.body, f_opt)

def typeMap(p: Prog, f: Type => Type) :Unit=
{
val f_opt = opt_func(f)
p.fdefs.foreach(typeMapFunc(_, f_opt))
p.moddefs.foreach(typeMapModule(_, f_opt))
}



/** Like [[Z3Context.mkAnd]], but automatically casts inputs to [[Z3BoolExpr]]s. */
def mkAnd(ctx: Z3Context, expressions: Z3AST *): Z3BoolExpr =
ctx.mkAnd(expressions.map(ast => ast.asInstanceOf[Z3BoolExpr]):_*)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/typechecker/Subtypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ object Subtypes {
}

def areEqual(t1: Type, t2: Type): Boolean = (t1, t2) match {
case (TSizedInt(l1, u1), TBool()) => l1.asInstanceOf[TBitWidthLen].len == 1 && u1.asInstanceOf[TSignedNess].unsigned()
case (TBool(), TSizedInt(l1, u1)) => l1.asInstanceOf[TBitWidthLen].len == 1 && u1.asInstanceOf[TSignedNess].unsigned()
case (TSizedInt(l1, u1), TBool()) => l1.asInstanceOf[TBitWidthLen].len == 1 && u1.unsigned()
case (TBool(), TSizedInt(l1, u1)) => l1.asInstanceOf[TBitWidthLen].len == 1 && u1.unsigned()
case (TSizedInt(l1, u1), TSizedInt(l2, u2)) => l1 == l2 && u1 == u2
case (TMemType(e1, as1, r1, w1, rp1, wp1),
TMemType(e2, as2, r2, w2, rp2, wp2))
Expand Down
Loading

0 comments on commit 9a5f533

Please sign in to comment.