From efdefde2a5fa13de8faa8c141f852391909225df Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Date: Tue, 9 Mar 2021 15:49:37 -0300 Subject: Create annotation to allow inline readmem in Verilog (#2107) This PR adds a new annotation allowing inline loading for memory files in Verilog code.--- src/main/scala/firrtl/EmissionOption.scala | 3 +++ .../firrtl/annotations/MemoryInitAnnotation.scala | 21 ++++++++++++++++++++- .../firrtl/backends/verilog/VerilogEmitter.scala | 12 +++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/scala/firrtl/EmissionOption.scala b/src/main/scala/firrtl/EmissionOption.scala index 074d9c28..90eb5851 100644 --- a/src/main/scala/firrtl/EmissionOption.scala +++ b/src/main/scala/firrtl/EmissionOption.scala @@ -2,6 +2,8 @@ package firrtl +import firrtl.annotations.MemoryLoadFileType + /** * Base type for emission customization options * NOTE: all the following traits must be mixed with SingleTargetAnnotation[T <: Named] @@ -18,6 +20,7 @@ sealed trait MemoryInitValue case object MemoryRandomInit extends MemoryInitValue case class MemoryScalarInit(value: BigInt) extends MemoryInitValue case class MemoryArrayInit(values: Seq[BigInt]) extends MemoryInitValue +case class MemoryFileInlineInit(filename: String, hexOrBinary: MemoryLoadFileType.FileType) extends MemoryInitValue /** default Emitter behavior for memories */ case object MemoryEmissionOptionDefault extends MemoryEmissionOption diff --git a/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala b/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala index 44656e0d..62dc96f4 100644 --- a/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala +++ b/src/main/scala/firrtl/annotations/MemoryInitAnnotation.scala @@ -2,7 +2,14 @@ package firrtl.annotations -import firrtl.{MemoryArrayInit, MemoryEmissionOption, MemoryInitValue, MemoryRandomInit, MemoryScalarInit} +import firrtl.{ + MemoryArrayInit, + MemoryEmissionOption, + MemoryFileInlineInit, + MemoryInitValue, + MemoryRandomInit, + MemoryScalarInit +} /** * Represents the initial value of the annotated memory. @@ -33,3 +40,15 @@ case class MemoryArrayInitAnnotation(target: ReferenceTarget, values: Seq[BigInt override def initValue: MemoryInitValue = MemoryArrayInit(values) override def isRandomInit: Boolean = false } + +/** Initialize the `target` memory with inline readmem[hb] statement. */ +case class MemoryFileInlineAnnotation( + target: ReferenceTarget, + filename: String, + hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex) + extends MemoryInitAnnotation { + require(filename.trim.nonEmpty, "empty filename not allowed in MemoryFileInlineAnnotation") + override def duplicate(n: ReferenceTarget): Annotation = copy(n) + override def initValue: MemoryInitValue = MemoryFileInlineInit(filename, hexOrBinary) + override def isRandomInit: Boolean = false +} diff --git a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala index f1650ad7..bc4996df 100644 --- a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala +++ b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala @@ -7,7 +7,7 @@ import firrtl.PrimOps._ import firrtl.Utils._ import firrtl.WrappedExpression._ import firrtl.traversals.Foreachers._ -import firrtl.annotations.{CircuitTarget, ReferenceTarget, SingleTargetAnnotation} +import firrtl.annotations.{CircuitTarget, MemoryLoadFileType, ReferenceTarget, SingleTargetAnnotation} import firrtl.passes.LowerTypes import firrtl.passes.MemPortUtils._ import firrtl.stage.TransformManager @@ -849,6 +849,16 @@ class VerilogEmitter extends SeqTransform with Emitter { rstring, ";" ) + case MemoryFileInlineInit(filename, hexOrBinary) => + val readmem = hexOrBinary match { + case MemoryLoadFileType.Binary => "$readmemb" + case MemoryLoadFileType.Hex => "$readmemh" + } + val inlineLoad = s""" + |initial begin + | $readmem("$filename", ${s.name}); + |end""".stripMargin + memoryInitials += Seq(inlineLoad) } } -- cgit v1.2.3