summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala
diff options
context:
space:
mode:
authorJack2022-01-12 04:27:19 +0000
committerJack2022-01-12 04:27:19 +0000
commit29df513e348cc809876893f650af8180f0190496 (patch)
tree06daaea954b4e5af7113f06e4bdbb78b33515cb3 /src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala
parent5242ce90659decb9058ee75db56e5c188029fbf9 (diff)
parent747d16311bdf185d2e98e452b14cb5d8ccca004c (diff)
Merge branch 'master' into 3.5-release
Diffstat (limited to 'src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala')
-rw-r--r--src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala95
1 files changed, 46 insertions, 49 deletions
diff --git a/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala b/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala
index 93981485..bd46abe9 100644
--- a/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala
+++ b/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala
@@ -3,7 +3,7 @@
package chisel3.util.experimental
import chisel3._
-import chisel3.experimental.{RunFirrtlTransform, annotate, ChiselAnnotation}
+import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform}
import firrtl.annotations._
import firrtl.ir.{Module => _, _}
import firrtl.transforms.BlackBoxInlineAnno
@@ -21,11 +21,11 @@ import scala.collection.mutable
case class ChiselLoadMemoryAnnotation[T <: Data](
target: MemBase[T],
fileName: String,
- hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex
-)
- extends ChiselAnnotation with RunFirrtlTransform {
+ hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex)
+ extends ChiselAnnotation
+ with RunFirrtlTransform {
- if(fileName.isEmpty) {
+ if (fileName.isEmpty) {
throw new Exception(
s"""LoadMemory from file annotations file empty file name"""
)
@@ -39,7 +39,6 @@ case class ChiselLoadMemoryAnnotation[T <: Data](
}
}
-
/** [[loadMemoryFromFile]] is an annotation generator that helps with loading a memory from a text file as a bind module. This relies on
* Verilator and Verilog's `\$readmemh` or `\$readmemb`. The [[https://github.com/freechipsproject/treadle Treadle
* backend]] can also recognize this annotation and load memory at run-time.
@@ -101,22 +100,20 @@ case class ChiselLoadMemoryAnnotation[T <: Data](
*/
object loadMemoryFromFile {
-
/** Annotate a memory such that it can be initialized using a file
* @param memory the memory
* @param filename the file used for initialization
* @param hexOrBinary whether the file uses a hex or binary number representation
*/
def apply[T <: Data](
- memory: MemBase[T],
- fileName: String,
+ memory: MemBase[T],
+ fileName: String,
hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex
): Unit = {
annotate(ChiselLoadMemoryAnnotation(memory, fileName, hexOrBinary))
}
}
-
/** [[loadMemoryFromFileInline]] is an annotation generator that helps with loading a memory from a text file inlined in
* the Verilog module. This relies on Verilator and Verilog's `\$readmemh` or `\$readmemb`.
* The [[https://github.com/freechipsproject/treadle Treadlebackend]] can also recognize this annotation and load memory at run-time.
@@ -179,15 +176,14 @@ object loadMemoryFromFile {
*/
object loadMemoryFromFileInline {
-
/** Annotate a memory such that it can be initialized inline using a file
* @param memory the memory
* @param fileName the file used for initialization
* @param hexOrBinary whether the file uses a hex or binary number representation
*/
def apply[T <: Data](
- memory: MemBase[T],
- fileName: String,
+ memory: MemBase[T],
+ fileName: String,
hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex
): Unit = {
annotate(new ChiselAnnotation {
@@ -204,14 +200,14 @@ object loadMemoryFromFileInline {
* not need this transform to do that.
*/
class LoadMemoryTransform extends Transform {
- def inputForm: CircuitForm = LowForm
+ def inputForm: CircuitForm = LowForm
def outputForm: CircuitForm = LowForm
private var memoryCounter: Int = -1
private val bindModules: mutable.ArrayBuffer[BlackBoxInlineAnno] = new mutable.ArrayBuffer()
- private val verilogEmitter: VerilogEmitter = new VerilogEmitter
+ private val verilogEmitter: VerilogEmitter = new VerilogEmitter
/** run the pass
* @param circuit the circuit
@@ -219,19 +215,19 @@ class LoadMemoryTransform extends Transform {
* @return
*/
def run(circuit: Circuit, annotations: AnnotationSeq): Circuit = {
- val groups = annotations
- .collect{ case m: LoadMemoryAnnotation => m }
+ val groups = annotations.collect { case m: LoadMemoryAnnotation => m }
.groupBy(_.target.serialize)
- val memoryAnnotations = groups.map { case (key, annos) =>
+ val memoryAnnotations = groups.map {
+ case (key, annos) =>
if (annos.size > 1) {
throw new Exception(
s"Multiple (${annos.size} found for memory $key one LoadMemoryAnnotation is allowed per memory"
)
}
key -> annos.head
- }
+ }
- val modulesByName = circuit.modules.collect { case module: firrtl.ir.Module => module.name -> module }.toMap
+ val modulesByName = circuit.modules.collect { case module: firrtl.ir.Module => module.name -> module }.toMap
/* Walk the module and for memories that are annotated with [[LoadMemoryAnnotation]]s generate the bindable modules for
* Verilog emission.
@@ -251,32 +247,34 @@ class LoadMemoryTransform extends Transform {
val writer = new java.io.StringWriter
val readmem = hexOrBinary match {
case MemoryLoadFileType.Binary => "$readmemb"
- case MemoryLoadFileType.Hex => "$readmemh"
+ case MemoryLoadFileType.Hex => "$readmemh"
}
modulesByName.get(moduleName.name).foreach { module =>
- val renderer = verilogEmitter.getRenderer(module, modulesByName)(writer)
- val loadFileName = lma.getFileName
-
- memoryCounter += 1
- val bindsToName = s"BindsTo_${memoryCounter}_${moduleName.name}"
- renderer.emitVerilogBind(bindsToName,
- s"""
- |initial begin
- | $readmem("$loadFileName", ${myModule.name}.$componentName);
- |end
- """.stripMargin)
- val inLineText = writer.toString + "\n" +
- s"""bind ${myModule.name} $bindsToName ${bindsToName}_Inst(.*);"""
-
- val blackBoxInline = BlackBoxInlineAnno(
- moduleName,
- moduleName.serialize + "." + componentName + ".v",
- inLineText
- )
-
- bindModules += blackBoxInline
- }
+ val renderer = verilogEmitter.getRenderer(module, modulesByName)(writer)
+ val loadFileName = lma.getFileName
+
+ memoryCounter += 1
+ val bindsToName = s"BindsTo_${memoryCounter}_${moduleName.name}"
+ renderer.emitVerilogBind(
+ bindsToName,
+ s"""
+ |initial begin
+ | $readmem("$loadFileName", ${myModule.name}.$componentName);
+ |end
+ """.stripMargin
+ )
+ val inLineText = writer.toString + "\n" +
+ s"""bind ${myModule.name} $bindsToName ${bindsToName}_Inst(.*);"""
+
+ val blackBoxInline = BlackBoxInlineAnno(
+ moduleName,
+ moduleName.serialize + "." + componentName + ".v",
+ inLineText
+ )
+
+ bindModules += blackBoxInline
+ }
case _ =>
}
@@ -284,8 +282,8 @@ class LoadMemoryTransform extends Transform {
def processStatements(statement: Statement): Statement = {
statement match {
- case m: DefMemory => processMemory(m.name)
- case s => s map processStatements
+ case m: DefMemory => processMemory(m.name)
+ case s => s.map(processStatements)
}
statement
}
@@ -299,7 +297,7 @@ class LoadMemoryTransform extends Transform {
myModule
}
- circuit map processModule
+ circuit.map(processModule)
}
def execute(state: CircuitState): CircuitState = {
@@ -309,11 +307,10 @@ class LoadMemoryTransform extends Transform {
case _ =>
false
}
- if(isVerilog) {
+ if (isVerilog) {
run(state.circuit, state.annotations)
state.copy(annotations = state.annotations ++ bindModules)
- }
- else {
+ } else {
state
}
}