diff options
| author | Jiuyang Liu | 2021-11-20 03:17:37 +0800 |
|---|---|---|
| committer | GitHub | 2021-11-19 19:17:37 +0000 |
| commit | b027eb466b033a0a9d229f19feb931ddb292a9fa (patch) | |
| tree | 6abd639ed2a8877f3a0eb743fd598ebff7e4c386 | |
| parent | c6093cbcd4f2eb8acd44f3b9d4e7146448de172f (diff) | |
Disable random init (#2396)
* Add option to disable random mem/reg init
Co-authored-by: Jiuyang Liu <liu@jiuyang.me>
* fix for code review.
Co-authored-by: SharzyL <me@sharzy.in>
5 files changed, 80 insertions, 5 deletions
diff --git a/src/main/scala/firrtl/EmissionOption.scala b/src/main/scala/firrtl/EmissionOption.scala index 90eb5851..530cc621 100644 --- a/src/main/scala/firrtl/EmissionOption.scala +++ b/src/main/scala/firrtl/EmissionOption.scala @@ -2,7 +2,7 @@ package firrtl -import firrtl.annotations.MemoryLoadFileType +import firrtl.annotations.{MemoryLoadFileType, NoTargetAnnotation} /** * Base type for emission customization options @@ -11,12 +11,26 @@ import firrtl.annotations.MemoryLoadFileType */ trait EmissionOption +/** Control how register initialization code is emitted */ +case class CustomDefaultRegisterEmission( + override val useInitAsPreset: Boolean, + override val disableRandomization: Boolean) + extends RegisterEmissionOption + with NoTargetAnnotation + +/** Customize how memory initialization code is emitted */ +case class CustomDefaultMemoryEmission(override val initValue: MemoryInitValue) + extends MemoryEmissionOption + with NoTargetAnnotation + /** Emission customization options for memories */ trait MemoryEmissionOption extends EmissionOption { def initValue: MemoryInitValue = MemoryRandomInit } +/** Emission customization option for memory initialization */ sealed trait MemoryInitValue +case object MemoryNoInit extends MemoryInitValue case object MemoryRandomInit extends MemoryInitValue case class MemoryScalarInit(value: BigInt) extends MemoryInitValue case class MemoryArrayInit(values: Seq[BigInt]) extends MemoryInitValue diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 40321621..98bb4127 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -193,6 +193,20 @@ object EmitAllModulesAnnotation extends HasShellOptions { helpText = "Run the specified module emitter (one protobuf per module)", shortOption = Some("p"), helpValueName = Some("<chirrtl|mhigh|high|middle|low|low-opt>") + ), + new ShellOption[String]( + longOption = "emission-options", + toAnnotationSeq = s => + s.split(",") + .map { + case "disableMemRandomization" => + CustomDefaultRegisterEmission(useInitAsPreset = true, disableRandomization = true) + case "disableRegisterRandomization" => CustomDefaultMemoryEmission(MemoryNoInit) + case a => throw new PhaseException(s"Unknown emission options '$a'! (Did you misspell it?)") + } + .toSeq, + helpText = "Options to disable random initialization for memory and registers", + helpValueName = Some("<disableMemRandomization,disableRegisterRandomization>") ) ) diff --git a/src/main/scala/firrtl/backends/experimental/rtlil/RtlilEmitter.scala b/src/main/scala/firrtl/backends/experimental/rtlil/RtlilEmitter.scala index 8c755e3d..a5f7f81f 100644 --- a/src/main/scala/firrtl/backends/experimental/rtlil/RtlilEmitter.scala +++ b/src/main/scala/firrtl/backends/experimental/rtlil/RtlilEmitter.scala @@ -996,8 +996,12 @@ private[firrtl] class EmissionOptionMap[V <: EmissionOption](val df: V) { private[firrtl] class EmissionOptions(annotations: AnnotationSeq) { // Private so that we can present an immutable API - private val memoryEmissionOption = new EmissionOptionMap[MemoryEmissionOption](MemoryEmissionOptionDefault) - private val registerEmissionOption = new EmissionOptionMap[RegisterEmissionOption](RegisterEmissionOptionDefault) + private val memoryEmissionOption = new EmissionOptionMap[MemoryEmissionOption]( + annotations.collectFirst { case a: CustomDefaultMemoryEmission => a }.getOrElse(MemoryEmissionOptionDefault) + ) + private val registerEmissionOption = new EmissionOptionMap[RegisterEmissionOption]( + annotations.collectFirst { case a: CustomDefaultRegisterEmission => a }.getOrElse(RegisterEmissionOptionDefault) + ) private val wireEmissionOption = new EmissionOptionMap[WireEmissionOption](WireEmissionOptionDefault) private val portEmissionOption = new EmissionOptionMap[PortEmissionOption](PortEmissionOptionDefault) private val nodeEmissionOption = new EmissionOptionMap[NodeEmissionOption](NodeEmissionOptionDefault) diff --git a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala index bef4be1f..af8996eb 100644 --- a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala +++ b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala @@ -466,8 +466,12 @@ class VerilogEmitter extends SeqTransform with Emitter { */ private[firrtl] class EmissionOptions(annotations: AnnotationSeq) { // Private so that we can present an immutable API - private val memoryEmissionOption = new EmissionOptionMap[MemoryEmissionOption](MemoryEmissionOptionDefault) - private val registerEmissionOption = new EmissionOptionMap[RegisterEmissionOption](RegisterEmissionOptionDefault) + private val memoryEmissionOption = new EmissionOptionMap[MemoryEmissionOption]( + annotations.collectFirst { case a: CustomDefaultMemoryEmission => a }.getOrElse(MemoryEmissionOptionDefault) + ) + private val registerEmissionOption = new EmissionOptionMap[RegisterEmissionOption]( + annotations.collectFirst { case a: CustomDefaultRegisterEmission => a }.getOrElse(RegisterEmissionOptionDefault) + ) private val wireEmissionOption = new EmissionOptionMap[WireEmissionOption](WireEmissionOptionDefault) private val portEmissionOption = new EmissionOptionMap[PortEmissionOption](PortEmissionOptionDefault) private val nodeEmissionOption = new EmissionOptionMap[NodeEmissionOption](NodeEmissionOptionDefault) @@ -905,6 +909,8 @@ class VerilogEmitter extends SeqTransform with Emitter { | end""".stripMargin memoryInitials += Seq(inlineLoad) } + case MemoryNoInit => + // do nothing } } diff --git a/src/test/scala/firrtlTests/VerilogEmitterTests.scala b/src/test/scala/firrtlTests/VerilogEmitterTests.scala index f4d13ac6..e533255a 100644 --- a/src/test/scala/firrtlTests/VerilogEmitterTests.scala +++ b/src/test/scala/firrtlTests/VerilogEmitterTests.scala @@ -835,6 +835,43 @@ class VerilogEmitterSpec extends FirrtlFlatSpec { ) result2 should containLine("assign z = ~(&x);") } + + it should "remove random line with Memory and Register with some emission option" in { + val input = + s"""|circuit Foo: + | module Foo: + | input clock: Clock + | input reset: UInt<1> + | input in_0: UInt<1> + | output out: UInt<1> + | mem mem : + | data-type => UInt<1> + | depth => 1 + | read-latency => 1 + | write-latency => 1 + | reader => r + | read-under-write => undefined + | reg tmp : UInt<1>, clock + | tmp <= in_0 + | mem.r.addr <= tmp + | mem.r.en <= UInt<1>(0) + | mem.r.clk <= clock + | out <= mem.r.data + |""".stripMargin + val circuit = Seq(ToWorkingIR, ResolveKinds, InferTypes).foldLeft(parse(input)) { case (c, p) => p.run(c) } + val state = CircuitState( + circuit, + LowForm, + Seq( + EmitCircuitAnnotation(classOf[VerilogEmitter]), + CustomDefaultMemoryEmission(MemoryNoInit), + CustomDefaultRegisterEmission(useInitAsPreset = true, disableRandomization = true) + ) + ) + val result = (new VerilogEmitter).execute(state) + (result.getEmittedCircuit.value should not).include("RANDOMIZE") + } + } class VerilogDescriptionEmitterSpec extends FirrtlFlatSpec { |
