Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Formal] Expose Btor2 target #4035

Merged
merged 12 commits into from
May 16, 2024
5 changes: 4 additions & 1 deletion src/main/scala/circt/stage/Annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ object CIRCTTarget {
/** The SystemVerilog language */
case object SystemVerilog extends Type

/* The btor2 format for bounded model checking */
case object Btor2 extends Type
}

/** Annotation that tells [[circt.stage.phases.CIRCT CIRCT]] what target to compile to */
Expand All @@ -73,10 +75,11 @@ object CIRCTTargetAnnotation extends HasShellOptions {
case "hw" => Seq(CIRCTTargetAnnotation(CIRCTTarget.HW))
case "verilog" => Seq(CIRCTTargetAnnotation(CIRCTTarget.Verilog))
case "systemverilog" => Seq(CIRCTTargetAnnotation(CIRCTTarget.SystemVerilog))
case "btor2" => Seq(CIRCTTargetAnnotation(CIRCTTarget.Btor2))
case a => throw new OptionsException(s"Unknown target name '$a'! (Did you misspell it?)")
},
helpText = "The CIRCT",
helpValueName = Some("{chirrtl|firrtl|hw|verilog|systemverilog}")
helpValueName = Some("{chirrtl|firrtl|hw|verilog|systemverilog|btor2}")
)
)

Expand Down
25 changes: 25 additions & 0 deletions src/main/scala/circt/stage/ChiselStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,31 @@ object ChiselStage {
Array("--target", "systemverilog") ++ args,
Seq(ChiselGeneratorAnnotation(() => gen)) ++ firtoolOpts.map(FirtoolOption(_))
)

/** Compile a Chisel circuit to btor2
*
* @param gen a call-by-name Chisel module
* @param args additional command line arguments to pass to Chisel
* @param firtoolOpts additional command line options to pass to firtool
* @return a string containing the btor2 output
*/
def emitBtor2(
gen: => RawModule,
args: Array[String] = Array.empty,
firtoolOpts: Array[String] = Array.empty
): String = {
val annos = Seq(
ChiselGeneratorAnnotation(() => gen),
CIRCTTargetAnnotation(CIRCTTarget.Btor2)
) ++ (new Shell("circt")).parse(args) ++ firtoolOpts.map(FirtoolOption(_))
phase
.transform(annos)
.collectFirst {
case EmittedVerilogCircuitAnnotation(a) => a
}
.get
.value
}
}

/** Command line entry point to [[ChiselStage]] */
Expand Down
16 changes: 16 additions & 0 deletions src/test/scala/circtTests/stage/ChiselStageSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,22 @@ class ChiselStageSpec extends AnyFunSpec with Matchers with chiselTests.Utils {
info(s"'$expectedOutput' exists")
}

it("should emit btor2 to string") {
import chisel3._
import chisel3.ltl._

class Counter extends Module {
val count = RegInit(0.U(32.W))
when(count === 42.U) { count := 0.U }
.otherwise { count := count + 1.U }

AssertProperty((count <= 42.U))
}

val btor2 = ChiselStage.emitBtor2(new ChiselStageSpec.Foo)
println(btor2)
dobios marked this conversation as resolved.
Show resolved Hide resolved
}

it("""should error if give a "--target-directory" option""") {

val exception = intercept[firrtl.options.OptionsException] {
Expand Down
Loading