From d048bb91e545950101adb9681eebc4a03fcc08d4 Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Tue, 9 Mar 2021 22:57:46 -0800 Subject: [PATCH] Add --target:fpga flag to prioritize FPGA-friendly compilation * Update name of FPGA flag based on Jack's comment * Add Scaladoc to describe what each constituent transform does * Add SeparateWriteClocks to --target:fpga --- src/main/scala/firrtl/stage/FirrtlCli.scala | 3 +- .../firrtl/stage/FirrtlCompilerTargets.scala | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/main/scala/firrtl/stage/FirrtlCompilerTargets.scala diff --git a/src/main/scala/firrtl/stage/FirrtlCli.scala b/src/main/scala/firrtl/stage/FirrtlCli.scala index 8be5fb74d4..9cfa6be9e5 100644 --- a/src/main/scala/firrtl/stage/FirrtlCli.scala +++ b/src/main/scala/firrtl/stage/FirrtlCli.scala @@ -22,7 +22,8 @@ trait FirrtlCli { this: Shell => NoCircuitDedupAnnotation, WarnNoScalaVersionDeprecation, PrettyNoExprInlining, - DisableFold + DisableFold, + OptimizeForFPGA ) .map(_.addOptions(parser)) diff --git a/src/main/scala/firrtl/stage/FirrtlCompilerTargets.scala b/src/main/scala/firrtl/stage/FirrtlCompilerTargets.scala new file mode 100644 index 0000000000..264e2cc161 --- /dev/null +++ b/src/main/scala/firrtl/stage/FirrtlCompilerTargets.scala @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 + +package firrtl.stage + +import firrtl.transforms._ +import firrtl.passes.memlib._ +import firrtl.options.{HasShellOptions, ShellOption} + +/** + * This flag enables a set of options that guide the FIRRTL compilation flow to ultimately + * generate Verilog that is more amenable to using for synthesized FPGA designs. Currently, this + * flag affects only memories, as the need to emit memories that support downstream inference of + * hardened RAM macros. These options are not intended to be specialized to any particular vendor; + * instead, they aim to emit simple Verilog that more closely reflects traditional human-written + * definitions of synchronous-read memories. + * + * 1) Allow some synchronous-read memories and readwrite ports to pass through VerilogMemDelays + * without introducing explicit pipeline registers or splitting ports. + * 2) Use the SimplifyMems transform to Lower aggregate-typed memories with always-high masks to + * packed memories without splitting. + * 3) Specify that memories with undefined read-under-write behavior should map to emitted + * microarchitectures characteristic of "read-first" ports by default. This eliminates the + * difficulty of inferring a RAM macro that matches the strict semantics of "write-first" ports. + * 4) Enable the InferReadWrite transform to reduce port count, where applicable. + */ +object OptimizeForFPGA extends HasShellOptions { + private val fpgaAnnos = Seq( + InferReadWriteAnnotation, + RunFirrtlTransformAnnotation(new InferReadWrite), + RunFirrtlTransformAnnotation(new SeparateWriteClocks), + DefaultReadFirstAnnotation, + RunFirrtlTransformAnnotation(new SetDefaultReadUnderWrite), + RunFirrtlTransformAnnotation(new SimplifyMems), + PassthroughSimpleSyncReadMemsAnnotation + ) + val options = Seq( + new ShellOption[Unit]( + longOption = "target:fpga", + toAnnotationSeq = a => fpgaAnnos, + helpText = "Choose compilation strategies that generally favor FPGA targets" + ) + ) +}