// // SPDX-License-Identifier: Apache-2.0
// package chisel3
// import scala.reflect.macros.blackbox.Context
// import scala.language.experimental.macros
// import chisel3.internal._
// import chisel3.internal.Builder.pushCommand
// import chisel3.internal.firrtl._
// import chisel3.internal.sourceinfo.SourceInfo
// import scala.reflect.macros.blackbox
// /** Scaladoc information for internal verification statement macros
// * that are used in objects assert, assume and cover.
// *
// * @groupdesc VerifPrintMacros
// *
// *
// * '''These internal methods are not part of the public-facing API!'''
// *
// *
// *
// * @groupprio VerifPrintMacros 1001
// */
// trait VerifPrintMacrosDoc
// object assert extends VerifPrintMacrosDoc {
// /** Checks for a condition to be valid in the circuit at rising clock edge
// * when not in reset. If the condition evaluates to false, the circuit
// * simulation stops with an error.
// *
// * @param cond condition, assertion fires (simulation fails) when false
// * @param message optional format string to print when the assertion fires
// * @param data optional bits to print in the message formatting
// *
// * @note See [[printf.apply(fmt:String* printf]] for format string documentation
// * @note currently cannot be used in core Chisel / libraries because macro
// * defs need to be compiled first and the SBT project is not set up to do
// * that
// */
// // Macros currently can't take default arguments, so we need two functions to emulate defaults.
// def apply(
// cond: Bool,
// message: String,
// data: Bits*
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assert = macro _applyMacroWithInterpolatorCheck
// /** Checks for a condition to be valid in the circuit at all times. If the
// * condition evaluates to false, the circuit simulation stops with an error.
// *
// * Does not fire when in reset (defined as the current implicit reset, e.g. as set by
// * the enclosing `withReset` or Module.reset.
// *
// * May be called outside of a Module (like defined in a function), so
// * functions using assert make the standard Module assumptions (single clock
// * and single reset).
// *
// * @param cond condition, assertion fires (simulation fails) on a rising clock edge when false and reset is not asserted
// * @param message optional chisel Printable type message
// *
// * @note See [[printf.apply(fmt:Printable)]] for documentation on printf using Printables
// * @note currently cannot be used in core Chisel / libraries because macro
// * defs need to be compiled first and the SBT project is not set up to do
// * that
// */
// def apply(
// cond: Bool,
// message: Printable
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assert = macro _applyMacroWithPrintableMessage
// def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assert =
// macro _applyMacroWithNoMessage
// import VerificationStatement._
// /** @group VerifPrintMacros */
// def _applyMacroWithInterpolatorCheck(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree,
// data: c.Tree*
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// message match {
// case q"scala.StringContext.apply(..$_).s(..$_)" =>
// c.warning(
// c.enclosingPosition,
// "The s-interpolator prints the Scala .toString of Data objects rather than the value " +
// "of the hardware wire during simulation. Use the cf-interpolator instead. If you want " +
// "an elaboration time check, call assert with a Boolean condition."
// )
// case _ =>
// }
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some(_root_.chisel3.Printable.pack($message, ..$data)))($sourceInfo, $compileOptions)"
// }
// /** An elaboration-time assertion. Calls the built-in Scala assert function. */
// def apply(cond: Boolean, message: => String): Unit = Predef.assert(cond, message)
// /** An elaboration-time assertion. Calls the built-in Scala assert function. */
// def apply(cond: Boolean): Unit = Predef.assert(cond, "")
// /** Named class for assertions. */
// final class Assert private[chisel3] () extends VerificationStatement
// /** @group VerifPrintMacros */
// @deprecated(
// "This method has been deprecated in favor of _applyMacroWithStringMessage. Please use the same.",
// "Chisel 3.5"
// )
// def _applyMacroWithMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree,
// data: c.Tree*
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)},_root_.scala.Some(_root_.chisel3.Printable.pack($message,..$data)))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithStringMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree,
// data: c.Tree*
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)},_root_.scala.Some(_root_.chisel3.Printable.pack($message,..$data)))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithPrintableMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some($message))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithNoMessage(
// c: blackbox.Context
// )(cond: c.Tree
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.None)($sourceInfo, $compileOptions)"
// }
// /** This will be removed in Chisel 3.6 in favor of the Printable version
// *
// * @group VerifPrintMacros
// */
// def _applyWithSourceLine(
// cond: Bool,
// line: SourceLineInfo,
// message: Option[String],
// data: Bits*
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assert = {
// val id = new Assert()
// when(!Module.reset.asBool()) {
// failureMessage("Assertion", line, cond, message.map(Printable.pack(_, data: _*)))
// Builder.pushCommand(Verification(id, Formal.Assert, sourceInfo, Module.clock.ref, cond.ref, ""))
// }
// id
// }
// /** @group VerifPrintMacros */
// def _applyWithSourceLinePrintable(
// cond: Bool,
// line: SourceLineInfo,
// message: Option[Printable]
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assert = {
// val id = new Assert()
// message.foreach(Printable.checkScope(_))
// when(!Module.reset.asBool()) {
// failureMessage("Assertion", line, cond, message)
// Builder.pushCommand(Verification(id, Formal.Assert, sourceInfo, Module.clock.ref, cond.ref, ""))
// }
// id
// }
// }
// object assume extends VerifPrintMacrosDoc {
// /** Assumes a condition to be valid in the circuit at all times.
// * Acts like an assertion in simulation and imposes a declarative
// * assumption on the state explored by formal tools.
// *
// * Does not fire when in reset (defined as the encapsulating Module's
// * reset). If your definition of reset is not the encapsulating Module's
// * reset, you will need to gate this externally.
// *
// * May be called outside of a Module (like defined in a function), so
// * functions using assert make the standard Module assumptions (single clock
// * and single reset).
// *
// * @param cond condition, assertion fires (simulation fails) when false
// * @param message optional format string to print when the assertion fires
// * @param data optional bits to print in the message formatting
// *
// * @note See [[printf.apply(fmt:String* printf]] for format string documentation
// */
// // Macros currently can't take default arguments, so we need two functions to emulate defaults.
// def apply(
// cond: Bool,
// message: String,
// data: Bits*
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assume = macro _applyMacroWithInterpolatorCheck
// /** Assumes a condition to be valid in the circuit at all times.
// * Acts like an assertion in simulation and imposes a declarative
// * assumption on the state explored by formal tools.
// *
// * Does not fire when in reset (defined as the encapsulating Module's
// * reset). If your definition of reset is not the encapsulating Module's
// * reset, you will need to gate this externally.
// *
// * May be called outside of a Module (like defined in a function), so
// * functions using assert make the standard Module assumptions (single clock
// * and single reset).
// *
// * @param cond condition, assertion fires (simulation fails) when false
// * @param message optional Printable type message when the assertion fires
// *
// * @note See [[printf.apply(fmt:Printable]] for documentation on printf using Printables
// */
// def apply(
// cond: Bool,
// message: Printable
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assume = macro _applyMacroWithPrintableMessage
// def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assume =
// macro _applyMacroWithNoMessage
// /** An elaboration-time assumption. Calls the built-in Scala assume function. */
// def apply(cond: Boolean, message: => String): Unit = Predef.assume(cond, message)
// /** An elaboration-time assumption. Calls the built-in Scala assume function. */
// def apply(cond: Boolean): Unit = Predef.assume(cond, "")
// /** Named class for assumptions. */
// final class Assume private[chisel3] () extends VerificationStatement
// import VerificationStatement._
// /** @group VerifPrintMacros */
// def _applyMacroWithInterpolatorCheck(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree,
// data: c.Tree*
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// message match {
// case q"scala.StringContext.apply(..$_).s(..$_)" =>
// c.warning(
// c.enclosingPosition,
// "The s-interpolator prints the Scala .toString of Data objects rather than the value " +
// "of the hardware wire during simulation. Use the cf-interpolator instead. If you want " +
// "an elaboration time check, call assert with a Boolean condition."
// )
// case _ =>
// }
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some(_root_.chisel3.Printable.pack($message, ..$data)))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// @deprecated(
// "This method has been deprecated in favor of _applyMacroWithStringMessage. Please use the same.",
// "Chisel 3.5"
// )
// def _applyMacroWithMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree,
// data: c.Tree*
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some(_root_.chisel3.Printable.pack($message, ..$data)))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithStringMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree,
// data: c.Tree*
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some(_root_.chisel3.Printable.pack($message, ..$data)))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithPrintableMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some($message))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithNoMessage(
// c: blackbox.Context
// )(cond: c.Tree
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLinePrintable"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.None)($sourceInfo, $compileOptions)"
// }
// /** This will be removed in Chisel 3.6 in favor of the Printable version
// *
// * @group VerifPrintMacros
// */
// def _applyWithSourceLine(
// cond: Bool,
// line: SourceLineInfo,
// message: Option[String],
// data: Bits*
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assume = {
// val id = new Assume()
// when(!Module.reset.asBool()) {
// failureMessage("Assumption", line, cond, message.map(Printable.pack(_, data: _*)))
// Builder.pushCommand(Verification(id, Formal.Assume, sourceInfo, Module.clock.ref, cond.ref, ""))
// }
// id
// }
// /** @group VerifPrintMacros */
// def _applyWithSourceLinePrintable(
// cond: Bool,
// line: SourceLineInfo,
// message: Option[Printable]
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Assume = {
// val id = new Assume()
// message.foreach(Printable.checkScope(_))
// when(!Module.reset.asBool()) {
// failureMessage("Assumption", line, cond, message)
// Builder.pushCommand(Verification(id, Formal.Assume, sourceInfo, Module.clock.ref, cond.ref, ""))
// }
// id
// }
// }
// object cover extends VerifPrintMacrosDoc {
// /** Declares a condition to be covered.
// * At ever clock event, a counter is incremented iff the condition is active
// * and reset is inactive.
// *
// * Does not fire when in reset (defined as the encapsulating Module's
// * reset). If your definition of reset is not the encapsulating Module's
// * reset, you will need to gate this externally.
// *
// * May be called outside of a Module (like defined in a function), so
// * functions using assert make the standard Module assumptions (single clock
// * and single reset).
// *
// * @param cond condition that will be sampled on every clock tick
// * @param message a string describing the cover event
// */
// // Macros currently can't take default arguments, so we need two functions to emulate defaults.
// def apply(cond: Bool, message: String)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover =
// macro _applyMacroWithMessage
// def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover =
// macro _applyMacroWithNoMessage
// /** Named class for cover statements. */
// final class Cover private[chisel3] () extends VerificationStatement
// import VerificationStatement._
// /** @group VerifPrintMacros */
// def _applyMacroWithNoMessage(
// c: blackbox.Context
// )(cond: c.Tree
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.None)($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyMacroWithMessage(
// c: blackbox.Context
// )(cond: c.Tree,
// message: c.Tree
// )(sourceInfo: c.Tree,
// compileOptions: c.Tree
// ): c.Tree = {
// import c.universe._
// val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine"))
// q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some($message))($sourceInfo, $compileOptions)"
// }
// /** @group VerifPrintMacros */
// def _applyWithSourceLine(
// cond: Bool,
// line: SourceLineInfo,
// message: Option[String]
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Cover = {
// val id = new Cover()
// when(!Module.reset.asBool()) {
// Builder.pushCommand(Verification(id, Formal.Cover, sourceInfo, Module.clock.ref, cond.ref, ""))
// }
// id
// }
// }
// object stop {
// /** Terminate execution, indicating success.
// *
// * @param message a string describing why the simulation was stopped
// */
// def apply(message: String = "")(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Stop = {
// val stp = new Stop()
// when(!Module.reset.asBool) {
// pushCommand(Stop(stp, sourceInfo, Builder.forcedClock.ref, 0))
// }
// stp
// }
// /** Terminate execution with a failure code. */
// @deprecated(
// "Non-zero return codes are not well supported. Please use assert(false.B) if you want to indicate a failure.",
// "Chisel 3.5"
// )
// def apply(code: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Stop = {
// val stp = new Stop()
// when(!Module.reset.asBool) {
// pushCommand(Stop(stp, sourceInfo, Builder.forcedClock.ref, code))
// }
// stp
// }
// /** Named class for [[stop]]s. */
// final class Stop private[chisel3] () extends VerificationStatement
// }
// /** Base class for all verification statements: Assert, Assume, Cover, Stop and Printf. */
// abstract class VerificationStatement extends NamedComponent {
// _parent.foreach(_.addId(this))
// }
// /** Helper functions for common functionality required by stop, assert, assume or cover */
// private object VerificationStatement {
// type SourceLineInfo = (String, Int, String)
// def getLine(c: blackbox.Context): SourceLineInfo = {
// val p = c.enclosingPosition
// (p.source.file.name, p.line, p.lineContent.trim)
// }
// def failureMessage(
// kind: String,
// lineInfo: SourceLineInfo,
// cond: Bool,
// message: Option[Printable]
// )(
// implicit sourceInfo: SourceInfo,
// compileOptions: CompileOptions
// ): Unit = {
// val (filename, line, content) = lineInfo
// val lineMsg = s"$filename:$line $content".replaceAll("%", "%%")
// val fmt = message match {
// case Some(msg) =>
// p"$kind failed: $msg\n at $lineMsg\n"
// case None => p"$kind failed\n at $lineMsg\n"
// }
// when(!cond) {
// printf.printfWithoutReset(fmt)
// }
// }
// }