[targetutils] Add Chisel-side API for labelling the reset condition

This commit is contained in:
David Biancolin 2021-06-17 00:41:39 +00:00
parent fa72045afc
commit 61ad72abc4
1 changed files with 72 additions and 0 deletions

View File

@ -0,0 +1,72 @@
// See LICENSE for license details.
package midas.targetutils
import chisel3.dontTouch
import chisel3.experimental.{ChiselAnnotation, annotate}
import firrtl.annotations._
import firrtl.transforms.DontTouchAllTargets
/**
* Masks off assertions, printfs, and autocounter events when the target bool is deasserted.
*
* Users typically wish to disable many forms instrumentation (e.g.,
* synthesized assertions and printfs, autocounters) while the target is
* under reset. By default, most of FireSim's instrumentations features mask
* off events using a module-local reset, generally Chisel's implicit reset.
* However, in some cases the module-local reset may not be asserted at the start of a
* reset sequence, leading to spurious assertion fires. This annotation
* provides a coarse-grained means to globally mask off these events until the
* target is sufficiently far in reset.
*
* Note, while it is possible to use this signal as a replacement for
* FireSim's trigger system, it is intended to support this time-zero reset
* case, and has different timing semantics.
* See: https://docs.fires.im/en/latest/Golden-Gate/Triggers.html
*
* @param target The boolean enable
*
*/
case class GlobalResetCondition(target: ReferenceTarget) extends
SingleTargetAnnotation[ReferenceTarget] with DontTouchAllTargets {
def duplicate(n: ReferenceTarget) = this.copy(target = n)
}
/**
* Indicates that this boolean target should be driven by the
* globalResetCondition if it is available.
*/
case class GlobalResetConditionSink(target: ReferenceTarget) extends
SingleTargetAnnotation[ReferenceTarget] with DontTouchAllTargets {
def duplicate(n: ReferenceTarget) = this.copy(target = n)
}
object GlobalResetCondition {
/**
* Label a bool as the global reset condition.
*
* @param target The chisel Bool to be annotated.
*/
def apply(target: chisel3.Bool): Unit = {
// Workaround: Prevent promote passthroughs from extracting the fanout
// generated by wiring the GlobalResetCondition to sink bridges, by
// introducing an identity logic function that it cannot "see" through.
//
// If we neglect this, the wiring pass may introduce combinational
// dependency between channels in two different domains, which currently is
// not checked for and will produce simulator deadlock.
val condition = PassthroughBlocker(target)
annotate(new ChiselAnnotation { def toFirrtl = GlobalResetCondition(condition.toTarget) })
}
/**
* Label a bool that should be driven by the global reset condition.
*
* @param target The chisel Bool to be annotated.
*/
def sink(target: chisel3.Bool): Unit = annotate(new ChiselAnnotation {
def toFirrtl = GlobalResetConditionSink(target.toTarget)
})
}