aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Magyar2021-03-09 22:57:46 -0800
committerAlbert Magyar2021-04-05 12:00:02 -0700
commit595d37213c57b3455a1c39b1cf93e37d01f41b3f (patch)
treeb8d2be36b1bc78241fc0033ea957d638c27be436 /src
parent872b282ff5bd7cc08f97a42e388b4e043454fe22 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/stage/FirrtlCli.scala3
-rw-r--r--src/main/scala/firrtl/stage/FirrtlCompilerTargets.scala52
2 files changed, 54 insertions, 1 deletions
diff --git a/src/main/scala/firrtl/stage/FirrtlCli.scala b/src/main/scala/firrtl/stage/FirrtlCli.scala
index 8be5fb74..9cfa6be9 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 00000000..c6975712
--- /dev/null
+++ b/src/main/scala/firrtl/stage/FirrtlCompilerTargets.scala
@@ -0,0 +1,52 @@
+// 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) Add a [[firrtl.passes.memlib.PassthroughSimpleSyncReadMemsAnnotation]] to allow some synchronous-read memories
+ * and readwrite ports to pass through [[firrtl.passes.memlib.VerilogMemDelays]] without introducing explicit
+ * pipeline registers or splitting ports.
+ *
+ * 2) Use the [[firrtl.transforms.SimplifyMems]] transform to Lower aggregate-typed memories with always-high masks to
+ * packed memories without splitting them into multiple independent ground-typed memories.
+ *
+ * 3) Use the [[firrtl.passes.memlib.SeparateWriteClocks]] transform to ensure that each write port of a
+ * multiple-write, synchronous-read memory with 'undefined' collision behavior ultimately maps to a separate clocked
+ * process in the emitted Verilog. This avoids the issue of implicitly constraining cross-port collision and write
+ * ordering behavior and helps simplify inference of true dual-port RAM macros.
+ *
+ * 4) Use the [[firrtl.passes.memlib.SetDefaultReadUnderWrite]] to 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.
+ *
+ * 5) Enable the [[firrtl.passes.memlib.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"
+ )
+ )
+}