aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorCarlos Eduardo2021-04-01 18:55:03 -0300
committerGitHub2021-04-01 14:55:03 -0700
commitd0d3cd4ec4348eea381fe463ac9c96956fdd5eba (patch)
tree3a035449ef49e5e7bca8f620339e18163285255e /src/main
parentffe83fa43b9269f1e899122ba7825025df173b5a (diff)
Add memory initialization options for synthesis (#2166)
This PR adds options for memory initialization inside or outside the `ifndef SYNTHESIS` block.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala6
-rw-r--r--src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala41
2 files changed, 44 insertions, 3 deletions
diff --git a/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala b/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala
index 62dc96f4..1e81301d 100644
--- a/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala
+++ b/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala
@@ -52,3 +52,9 @@ case class MemoryFileInlineAnnotation(
override def initValue: MemoryInitValue = MemoryFileInlineInit(filename, hexOrBinary)
override def isRandomInit: Boolean = false
}
+
+/** Initializes the memory inside the `ifndef SYNTHESIS` block (default) */
+case object MemoryNoSynthInit extends NoTargetAnnotation
+
+/** Initializes the memory outside the `ifndef SYNTHESIS` block */
+case object MemorySynthInit extends NoTargetAnnotation
diff --git a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala
index 33c6b9a8..f854b33a 100644
--- a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala
+++ b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala
@@ -7,7 +7,14 @@ import firrtl.PrimOps._
import firrtl.Utils._
import firrtl.WrappedExpression._
import firrtl.traversals.Foreachers._
-import firrtl.annotations.{CircuitTarget, MemoryLoadFileType, ReferenceTarget, SingleTargetAnnotation}
+import firrtl.annotations.{
+ CircuitTarget,
+ MemoryLoadFileType,
+ MemoryNoSynthInit,
+ MemorySynthInit,
+ ReferenceTarget,
+ SingleTargetAnnotation
+}
import firrtl.passes.LowerTypes
import firrtl.passes.MemPortUtils._
import firrtl.stage.TransformManager
@@ -482,6 +489,21 @@ class VerilogEmitter extends SeqTransform with Emitter {
def getConnectEmissionOption(target: ReferenceTarget): ConnectEmissionOption =
connectEmissionOption(target)
+ // Defines the memory initialization based on the annotation
+ // Defaults to having the memories inside the `ifndef SYNTHESIS` block
+ def emitMemoryInitAsNoSynth: Boolean = {
+ val annos = annotations.collect { case a @ (MemoryNoSynthInit | MemorySynthInit) => a }
+ annos match {
+ case Seq() => true
+ case Seq(MemoryNoSynthInit) => true
+ case Seq(MemorySynthInit) => false
+ case other =>
+ throw new FirrtlUserException(
+ "There should only be at most one memory initialization option annotation, got $other"
+ )
+ }
+ }
+
private val emissionAnnos = annotations.collect {
case m: SingleTargetAnnotation[ReferenceTarget] @unchecked with EmissionOption => m
}
@@ -861,7 +883,14 @@ class VerilogEmitter extends SeqTransform with Emitter {
case MemoryLoadFileType.Binary => "$readmemb"
case MemoryLoadFileType.Hex => "$readmemh"
}
- memoryInitials += Seq(s"""$readmem("$filename", ${s.name});""")
+ if (emissionOptions.emitMemoryInitAsNoSynth) {
+ memoryInitials += Seq(s"""$readmem("$filename", ${s.name});""")
+ } else {
+ val inlineLoad = s"""initial begin
+ | $readmem("$filename", ${s.name});
+ | end""".stripMargin
+ memoryInitials += Seq(inlineLoad)
+ }
}
}
@@ -1200,13 +1229,19 @@ class VerilogEmitter extends SeqTransform with Emitter {
for (x <- initials) emit(Seq(tab, x))
for (x <- asyncInitials) emit(Seq(tab, x))
emit(Seq(" `endif // RANDOMIZE"))
- for (x <- memoryInitials) emit(Seq(tab, x))
+
+ if (emissionOptions.emitMemoryInitAsNoSynth) {
+ for (x <- memoryInitials) emit(Seq(tab, x))
+ }
emit(Seq("end // initial"))
// User-defined macro of code to run after an initial block
emit(Seq("`ifdef FIRRTL_AFTER_INITIAL"))
emit(Seq("`FIRRTL_AFTER_INITIAL"))
emit(Seq("`endif"))
emit(Seq("`endif // SYNTHESIS"))
+ if (!emissionOptions.emitMemoryInitAsNoSynth) {
+ for (x <- memoryInitials) emit(Seq(tab, x))
+ }
}
if (formals.keys.nonEmpty) {