diff --git a/core/src/main/scala/chisel3/VerificationStatement.scala b/core/src/main/scala/chisel3/VerificationStatement.scala index b4415dd04b4..4b1903a7dd4 100644 --- a/core/src/main/scala/chisel3/VerificationStatement.scala +++ b/core/src/main/scala/chisel3/VerificationStatement.scala @@ -401,20 +401,34 @@ object cover extends VerifPrintMacrosDoc { object stop { - /** Terminate execution, indicating success. + /** Terminate execution, indicating success and printing a message. * - * @param message a string describing why the simulation was stopped + * @param message a message describing why simulation was stopped */ - def apply(message: String = "")(implicit sourceInfo: SourceInfo): Stop = { - val stp = new Stop() - when(!Module.reset.asBool) { - pushCommand(Stop(stp, sourceInfo, Builder.forcedClock.ref, 0)) - } - stp - } + def apply(message: String)(implicit sourceInfo: SourceInfo): Stop = buildStopCommand(Some(PString(message))) + + /** Terminate execution, indicating success and printing a message. + * + * @param message a printable describing why simulation was stopped + */ + def apply(message: Printable)(implicit sourceInfo: SourceInfo): Stop = buildStopCommand(Some(message)) + + /** Terminate execution, indicating success. + */ + def apply()(implicit sourceInfo: SourceInfo): Stop = buildStopCommand(None) /** Named class for [[stop]]s. */ final class Stop private[chisel3] () extends VerificationStatement + + private def buildStopCommand(message: Option[Printable])(implicit sourceInfo: SourceInfo): Stop = { + val stopId = new Stop() + message.foreach(Printable.checkScope(_)) + when(!Module.reset.asBool) { + message.foreach(printf.printfWithoutReset(_)) + pushCommand(Stop(stopId, sourceInfo, Builder.forcedClock.ref, 0)) + } + stopId + } } /** Base class for all verification statements: Assert, Assume, Cover, Stop and Printf. */ diff --git a/src/test/scala/chiselTests/Stop.scala b/src/test/scala/chiselTests/Stop.scala index 25aae2d9cdf..c550bdf6901 100644 --- a/src/test/scala/chiselTests/Stop.scala +++ b/src/test/scala/chiselTests/Stop.scala @@ -4,16 +4,25 @@ package chiselTests import chisel3._ import chisel3.testers.BasicTester +import _root_.circt.stage.ChiselStage class StopTester() extends BasicTester { - stop() + chisel3.stop() +} + +class StopWithMessageTester() extends BasicTester { + val cycle = RegInit(0.U(4.W)) + cycle := cycle + 1.U + when(cycle === 4.U) { + chisel3.stop(cf"cycle: $cycle") + } } class StopImmediatelyTester extends BasicTester { val cycle = RegInit(0.asUInt(4.W)) cycle := cycle + 1.U when(cycle === 4.U) { - stop() + chisel3.stop() } assert(cycle =/= 5.U, "Simulation did not exit upon executing stop()") } @@ -23,6 +32,11 @@ class StopSpec extends ChiselFlatSpec { assertTesterPasses { new StopTester } } + it should "emit an optional message with arguments" in { + val chirrtl = ChiselStage.emitCHIRRTL(new StopWithMessageTester) + chirrtl should include("\"cycle: %d\", cycle") + } + it should "end the simulation immediately" in { assertTesterPasses { new StopImmediatelyTester } }