diff options
| author | Adam Izraelevitz | 2016-10-17 15:10:12 -0700 |
|---|---|---|
| committer | GitHub | 2016-10-17 15:10:12 -0700 |
| commit | 7d08b9a1486fef0459481f6e542464a29fbe1db5 (patch) | |
| tree | e8b2289ac5cbecbd59d58cab8bd503287818ec5d /src/main/scala/firrtl/passes/ConvertFixedToSInt.scala | |
| parent | 2848d87721df110d0425114283cb5fa7e6c2ee03 (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.scala | 119 |
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: |
