From 334c9bbe5061a3bcb72df971ec555de7df0ba36c Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Fri, 25 Jan 2019 14:04:16 -0500 Subject: Add "mverilog" Compiler Option, Compiler Fixes This adds "mverilog" to the "--compiler" command line option. This will run the MinimumVerilogCompiler. This additionally fixes the MinimumVerilogCompiler such that DeadCodeElimination will not be run (it's not supposed to be). This is done by adding a MinimumVerilogEmitter, subclassing VerilogVerilog, that strips the DeadCodeElimination step from its parent. Additionally, BlackBoxSourceHelper is removed from the MinimumVerilogCompiler since this will be run by the VerilogEmitter already. Signed-off-by: Schuyler Eldridge --- src/main/scala/firrtl/Emitter.scala | 10 +++++++++ .../scala/firrtl/ExecutionOptionsManager.scala | 26 +++++++++++++--------- src/main/scala/firrtl/LoweringCompilers.scala | 4 ++-- 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'src/main') diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 67bd1583..8049e33c 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -882,3 +882,13 @@ class VerilogEmitter extends SeqTransform with Emitter { state.copy(annotations = newAnnos ++ state.annotations) } } + +class MinimumVerilogEmitter extends VerilogEmitter with Emitter { + + + override def transforms = super.transforms.filter{ + case _: DeadCodeElimination => false + case _ => true + } + +} diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala index 16e30f3a..47083cb4 100644 --- a/src/main/scala/firrtl/ExecutionOptionsManager.scala +++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala @@ -207,18 +207,19 @@ extends ComposableOptions { case "low" => new LowFirrtlCompiler() case "middle" => new MiddleFirrtlCompiler() case "verilog" => new VerilogCompiler() + case "mverilog" => new MinimumVerilogCompiler() case "sverilog" => new SystemVerilogCompiler() } } def outputSuffix: String = { compilerName match { - case "verilog" => "v" - case "sverilog" => "sv" - case "low" => "lo.fir" - case "middle" => "mid.fir" - case "high" => "hi.fir" - case "none" => "fir" + case "verilog" | "mverilog" => "v" + case "sverilog" => "sv" + case "low" => "lo.fir" + case "middle" => "mid.fir" + case "high" => "hi.fir" + case "none" => "fir" case _ => throw new Exception(s"Illegal compiler name $compilerName") } @@ -267,6 +268,7 @@ extends ComposableOptions { case "middle" => classOf[MiddleFirrtlEmitter] case "low" => classOf[LowFirrtlEmitter] case "verilog" => classOf[VerilogEmitter] + case "mverilog" => classOf[MinimumVerilogEmitter] case "sverilog" => classOf[VerilogEmitter] } getOutputConfig(optionsManager) match { @@ -344,13 +346,16 @@ trait HasFirrtlOptions { parser.opt[String]("compiler") .abbr("X") - .valueName ("") + .valueName ("") .foreach { x => firrtlOptions = firrtlOptions.copy(compilerName = x) } .validate { x => - if (Array("high", "middle", "low", "verilog", "sverilog", "none").contains(x.toLowerCase)) parser.success - else parser.failure(s"$x not a legal compiler") + if (Array("high", "middle", "low", "verilog", "mverilog", "sverilog", "none").contains(x.toLowerCase)) { + parser.success + } else { + parser.failure(s"$x not a legal compiler") + } }.text { s"compiler to use, default is ${firrtlOptions.compilerName}" } @@ -492,7 +497,8 @@ object FirrtlExecutionSuccess { * Indicates a successful execution of the firrtl compiler, returning the compiled result and * the type of compile * - * @param emitType The name of the compiler used, currently "high", "middle", "low", "verilog", or "sverilog" + * @param emitType The name of the compiler used, currently "high", "middle", "low", "verilog", "mverilog", or + * "sverilog" * @param emitted The emitted result of compilation */ class FirrtlExecutionSuccess( diff --git a/src/main/scala/firrtl/LoweringCompilers.scala b/src/main/scala/firrtl/LoweringCompilers.scala index eab928c2..7499d6d1 100644 --- a/src/main/scala/firrtl/LoweringCompilers.scala +++ b/src/main/scala/firrtl/LoweringCompilers.scala @@ -166,9 +166,9 @@ class VerilogCompiler extends Compiler { /** Emits Verilog without optimizations */ class MinimumVerilogCompiler extends Compiler { - def emitter = new VerilogEmitter + def emitter = new MinimumVerilogEmitter def transforms: Seq[Transform] = getLoweringTransforms(ChirrtlForm, LowForm) ++ - Seq(new MinimumLowFirrtlOptimization, new BlackBoxSourceHelper) + Seq(new MinimumLowFirrtlOptimization) } /** Currently just an alias for the [[VerilogCompiler]] */ -- cgit v1.2.3 From a77122b4bb8756636c169473af3dc367b14698ef Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Tue, 5 Feb 2019 11:23:19 -0500 Subject: Add RemoveValidIf to -X mverilog This adds the RemoveValidIf Pass to the MinimumLowFirrtlOptimization Transform. A test case is included to verify that `is invalid` is properly converted to a connection to zero. Signed-off-by: Schuyler Eldridge --- src/main/scala/firrtl/LoweringCompilers.scala | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main') diff --git a/src/main/scala/firrtl/LoweringCompilers.scala b/src/main/scala/firrtl/LoweringCompilers.scala index 7499d6d1..9969150d 100644 --- a/src/main/scala/firrtl/LoweringCompilers.scala +++ b/src/main/scala/firrtl/LoweringCompilers.scala @@ -119,6 +119,7 @@ class MinimumLowFirrtlOptimization extends CoreTransform { def inputForm = LowForm def outputForm = LowForm def transforms = Seq( + passes.RemoveValidIf, passes.Legalize, passes.memlib.VerilogMemDelays, // TODO move to Verilog emitter passes.SplitExpressions) -- cgit v1.2.3 From 0a88492bfbbfe7e446b74776ec59cab69e73585b Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Tue, 5 Feb 2019 14:03:08 -0500 Subject: Do Shr constant propagation in Legalize This uses the foldShiftRight method of the ConstantPropagation Transform when legalizing Shr PrimOps. This has the effect of removing literals with bit extracts from the MinimumVerilogCompiler. This makes the formerly private foldShiftRight method of a public method of the ConstantPropagation companion object. Tests in the MimimumVerilogCompilerSpec are updated to check that Shr is handled as intended. Signed-off-by: Schuyler Eldridge --- src/main/scala/firrtl/passes/Passes.scala | 30 ++++++++++++---------- .../firrtl/transforms/ConstantPropagation.scala | 22 ++++++++-------- 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src/main') diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala index bb65201b..04bfb19c 100644 --- a/src/main/scala/firrtl/passes/Passes.scala +++ b/src/main/scala/firrtl/passes/Passes.scala @@ -183,19 +183,23 @@ object ExpandConnects extends Pass { object Legalize extends Pass { private def legalizeShiftRight(e: DoPrim): Expression = { require(e.op == Shr) - 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 + 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 = { diff --git a/src/main/scala/firrtl/transforms/ConstantPropagation.scala b/src/main/scala/firrtl/transforms/ConstantPropagation.scala index 54338719..6618312a 100644 --- a/src/main/scala/firrtl/transforms/ConstantPropagation.scala +++ b/src/main/scala/firrtl/transforms/ConstantPropagation.scala @@ -45,6 +45,17 @@ object ConstantPropagation { case _ => e } } + + def foldShiftRight(e: DoPrim) = e.consts.head.toInt match { + case 0 => e.args.head + case x => e.args.head match { + // TODO when amount >= x.width, return a zero-width wire + case UIntLiteral(v, IntWidth(w)) => UIntLiteral(v >> x, IntWidth((w - x) max 1)) + // take sign bit if shift amount is larger than arg width + case SIntLiteral(v, IntWidth(w)) => SIntLiteral(v >> x, IntWidth((w - x) max 1)) + case _ => e + } + } } class ConstantPropagation extends Transform with ResolvedAnnotationPaths { @@ -144,17 +155,6 @@ class ConstantPropagation extends Transform with ResolvedAnnotationPaths { case _ => e } - private def foldShiftRight(e: DoPrim) = e.consts.head.toInt match { - case 0 => e.args.head - case x => e.args.head match { - // TODO when amount >= x.width, return a zero-width wire - case UIntLiteral(v, IntWidth(w)) => UIntLiteral(v >> x, IntWidth((w - x) max 1)) - // take sign bit if shift amount is larger than arg width - case SIntLiteral(v, IntWidth(w)) => SIntLiteral(v >> x, IntWidth((w - x) max 1)) - case _ => e - } - } - private def foldDynamicShiftRight(e: DoPrim) = e.args.last match { case UIntLiteral(v, IntWidth(w)) => val shr = DoPrim(Shr, Seq(e.args.head), Seq(v), UnknownType) -- cgit v1.2.3