diff options
| author | Adam Izraelevitz | 2020-04-10 12:47:33 -0700 |
|---|---|---|
| committer | GitHub | 2020-04-10 19:47:33 +0000 |
| commit | 54ff9451f285cc18bca0ab519e013ff8326538b8 (patch) | |
| tree | fff7384be0131e52249b245fe78e18f413fc0c61 /src/main/scala/firrtl/passes/Legalize.scala | |
| parent | 632930723adc2f78d4d6445acf5f8bcc250a6c0c (diff) | |
Split Passes.scala into separate files (#1496)
* Split Passes.scala into separate files
* Add imports of implicit things
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Diffstat (limited to 'src/main/scala/firrtl/passes/Legalize.scala')
| -rw-r--r-- | src/main/scala/firrtl/passes/Legalize.scala | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/passes/Legalize.scala b/src/main/scala/firrtl/passes/Legalize.scala new file mode 100644 index 00000000..37556769 --- /dev/null +++ b/src/main/scala/firrtl/passes/Legalize.scala @@ -0,0 +1,89 @@ +package firrtl.passes + +import firrtl.PrimOps._ +import firrtl.Utils.{BoolType, error, zero} +import firrtl.ir._ +import firrtl.options.{PreservesAll, Dependency} +import firrtl.transforms.ConstantPropagation +import firrtl.{Transform, bitWidth} +import firrtl.Mappers._ + +// Replace shr by amount >= arg width with 0 for UInts and MSB for SInts +// TODO replace UInt with zero-width wire instead +object Legalize extends Pass with PreservesAll[Transform] { + + override val prerequisites = firrtl.stage.Forms.MidForm :+ Dependency(LowerTypes) + + override val optionalPrerequisites = Seq.empty + + override val dependents = Seq.empty + + private def legalizeShiftRight(e: DoPrim): Expression = { + require(e.op == Shr) + e.args.head match { + case _: UIntLiteral | _: SIntLiteral => ConstantPropagation.foldShiftRight(e) + case _ => + val amount = e.consts.head.toInt + val width = bitWidth(e.args.head.tpe) + lazy val msb = width - 1 + if (amount >= width) { + e.tpe match { + case UIntType(_) => zero + case SIntType(_) => + val bits = DoPrim(Bits, e.args, Seq(msb, msb), BoolType) + DoPrim(AsSInt, Seq(bits), Seq.empty, SIntType(IntWidth(1))) + case t => error(s"Unsupported type $t for Primop Shift Right") + } + } else { + e + } + } + } + private def legalizeBitExtract(expr: DoPrim): Expression = { + expr.args.head match { + case _: UIntLiteral | _: SIntLiteral => ConstantPropagation.constPropBitExtract(expr) + case _ => expr + } + } + private def legalizePad(expr: DoPrim): Expression = expr.args.head match { + case UIntLiteral(value, IntWidth(width)) if width < expr.consts.head => + UIntLiteral(value, IntWidth(expr.consts.head)) + case SIntLiteral(value, IntWidth(width)) if width < expr.consts.head => + SIntLiteral(value, IntWidth(expr.consts.head)) + case _ => expr + } + private def legalizeConnect(c: Connect): Statement = { + val t = c.loc.tpe + val w = bitWidth(t) + if (w >= bitWidth(c.expr.tpe)) { + c + } else { + val bits = DoPrim(Bits, Seq(c.expr), Seq(w - 1, 0), UIntType(IntWidth(w))) + val expr = t match { + case UIntType(_) => bits + case SIntType(_) => DoPrim(AsSInt, Seq(bits), Seq(), SIntType(IntWidth(w))) + case FixedType(_, IntWidth(p)) => DoPrim(AsFixedPoint, Seq(bits), Seq(p), t) + } + Connect(c.info, c.loc, expr) + } + } + def run (c: Circuit): Circuit = { + def legalizeE(expr: Expression): Expression = expr map legalizeE match { + case prim: DoPrim => prim.op match { + case Shr => legalizeShiftRight(prim) + case Pad => legalizePad(prim) + case Bits | Head | Tail => legalizeBitExtract(prim) + case _ => prim + } + case e => e // respect pre-order traversal + } + def legalizeS (s: Statement): Statement = { + val legalizedStmt = s match { + case c: Connect => legalizeConnect(c) + case _ => s + } + legalizedStmt map legalizeS map legalizeE + } + c copy (modules = c.modules map (_ map legalizeS)) + } +} |
