aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/ConvertFixedToSInt.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/passes/ConvertFixedToSInt.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/passes/ConvertFixedToSInt.scala')
-rw-r--r--src/main/scala/firrtl/passes/ConvertFixedToSInt.scala119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/passes/ConvertFixedToSInt.scala b/src/main/scala/firrtl/passes/ConvertFixedToSInt.scala
new file mode 100644
index 00000000..8cf0b890
--- /dev/null
+++ b/src/main/scala/firrtl/passes/ConvertFixedToSInt.scala
@@ -0,0 +1,119 @@
+package firrtl.passes
+
+import scala.collection.mutable
+import firrtl.PrimOps._
+import firrtl.ir._
+import firrtl._
+import firrtl.Mappers._
+import firrtl.Utils.{sub_type, module_type, field_type, BoolType, max, min, pow_minus_one}
+
+/** Replaces FixedType with SIntType, and correctly aligns all binary points
+ */
+object ConvertFixedToSInt extends Pass {
+ def name = "Convert Fixed Types to SInt Types"
+ def alignArg(e: Expression, point: BigInt): Expression = e.tpe match {
+ case FixedType(IntWidth(w), IntWidth(p)) => // assert(point >= p)
+ if((point - p) > 0) {
+ DoPrim(Shl, Seq(e), Seq(point - p), UnknownType)
+ } else if (point - p < 0) {
+ DoPrim(Shr, Seq(e), Seq(p - point), UnknownType)
+ } else e
+ case FixedType(w, p) => error("Shouldn't be here")
+ case _ => e
+ }
+ def calcPoint(es: Seq[Expression]): BigInt =
+ es.map(_.tpe match {
+ case FixedType(IntWidth(w), IntWidth(p)) => p
+ case _ => BigInt(0)
+ }).reduce(max(_, _))
+ def toSIntType(t: Type): Type = t match {
+ case FixedType(IntWidth(w), IntWidth(p)) => SIntType(IntWidth(w))
+ case FixedType(w, p) => error("Shouldn't be here")
+ case _ => t
+ }
+ def run(c: Circuit): Circuit = {
+ val moduleTypes = mutable.HashMap[String,Type]()
+ def onModule(m:DefModule) : DefModule = {
+ val types = mutable.HashMap[String,Type]()
+ def updateExpType(e:Expression): Expression = e match {
+ case DoPrim(Mul, args, consts, tpe) => e map updateExpType
+ case DoPrim(AsFixedPoint, args, consts, tpe) => DoPrim(AsSInt, args, Seq.empty, tpe)
+ case DoPrim(BPShl, args, consts, tpe) => DoPrim(Shl, args, consts, tpe)
+ case DoPrim(BPShr, args, consts, tpe) => DoPrim(Shr, args, consts, tpe)
+ case DoPrim(BPSet, args, consts, FixedType(w, IntWidth(p))) => alignArg(args.head, p)
+ case DoPrim(op, args, consts, tpe) =>
+ val point = calcPoint(args)
+ val newExp = DoPrim(op, args.map(x => alignArg(x, point)), consts, UnknownType)
+ newExp map updateExpType match {
+ case DoPrim(AsFixedPoint, args, consts, tpe) => DoPrim(AsSInt, args, Seq.empty, tpe)
+ case e => e
+ }
+ case Mux(cond, tval, fval, tpe) =>
+ val point = calcPoint(Seq(tval, fval))
+ val newExp = Mux(cond, alignArg(tval, point), alignArg(fval, point), UnknownType)
+ newExp map updateExpType
+ case e: UIntLiteral => e
+ case e: SIntLiteral => e
+ case _ => e map updateExpType match {
+ case ValidIf(cond, value, tpe) => ValidIf(cond, value, value.tpe)
+ case WRef(name, tpe, k, g) => WRef(name, types(name), k, g)
+ case WSubField(exp, name, tpe, g) => WSubField(exp, name, field_type(exp.tpe, name), g)
+ case WSubIndex(exp, value, tpe, g) => WSubIndex(exp, value, sub_type(exp.tpe), g)
+ case WSubAccess(exp, index, tpe, g) => WSubAccess(exp, index, sub_type(exp.tpe), g)
+ }
+ }
+ def updateStmtType(s: Statement): Statement = s match {
+ case DefRegister(info, name, tpe, clock, reset, init) =>
+ val newType = toSIntType(tpe)
+ types(name) = newType
+ DefRegister(info, name, newType, clock, reset, init) map updateExpType
+ case DefWire(info, name, tpe) =>
+ val newType = toSIntType(tpe)
+ types(name) = newType
+ DefWire(info, name, newType)
+ case DefNode(info, name, value) =>
+ val newValue = updateExpType(value)
+ val newType = toSIntType(newValue.tpe)
+ types(name) = newType
+ DefNode(info, name, newValue)
+ case DefMemory(info, name, dt, depth, wL, rL, rs, ws, rws, ruw) =>
+ val newStmt = DefMemory(info, name, toSIntType(dt), depth, wL, rL, rs, ws, rws, ruw)
+ val newType = MemPortUtils.memType(newStmt)
+ types(name) = newType
+ newStmt
+ case WDefInstance(info, name, module, tpe) =>
+ val newType = moduleTypes(module)
+ types(name) = newType
+ WDefInstance(info, name, module, newType)
+ case Connect(info, loc, exp) =>
+ val point = calcPoint(Seq(loc))
+ val newExp = alignArg(exp, point)
+ Connect(info, loc, newExp) map updateExpType
+ case PartialConnect(info, loc, exp) =>
+ val point = calcPoint(Seq(loc))
+ val newExp = alignArg(exp, point)
+ PartialConnect(info, loc, newExp) map updateExpType
+ // check Connect case, need to shl
+ case s => (s map updateStmtType) map updateExpType
+ }
+
+ m.ports.foreach(p => types(p.name) = p.tpe)
+ m match {
+ case Module(info, name, ports, body) => Module(info,name,ports,updateStmtType(body))
+ case m:ExtModule => m
+ }
+ }
+
+ val newModules = for(m <- c.modules) yield {
+ val newPorts = m.ports.map(p => Port(p.info,p.name,p.direction,toSIntType(p.tpe)))
+ m match {
+ case Module(info, name, ports, body) => Module(info,name,newPorts,body)
+ case ExtModule(info, name, ports) => ExtModule(info,name,newPorts)
+ }
+ }
+ newModules.foreach(m => moduleTypes(m.name) = module_type(m))
+ firrtl.passes.InferTypes.run(Circuit(c.info, newModules.map(onModule(_)), c.main ))
+ }
+}
+
+// vim: set ts=4 sw=4 et: