Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

Commit

Permalink
Add pono backend to chisel formal for bmc
Browse files Browse the repository at this point in the history
  • Loading branch information
Gallagator committed Jan 16, 2024
1 parent b2d8908 commit 74365bb
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
backend: [z3, cvc4, btormc, bitwuzla]
backend: [z3, cvc4, btormc, bitwuzla, pono]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
7 changes: 5 additions & 2 deletions src/main/scala/chiseltest/formal/backends/Maltese.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package chiseltest.formal.backends

import chiseltest.formal.backends.btor.BtormcModelChecker
import chiseltest.formal.backends.btor._
import chiseltest.formal.backends.smt._
import chiseltest.formal.{DoNotModelUndef, DoNotOptimizeFormal, FailedBoundedCheckException}
import firrtl2._
Expand Down Expand Up @@ -56,6 +56,8 @@ private case object BoolectorEngineAnnotation extends FormalEngineAnnotation
*/
case object BitwuzlaEngineAnnotation extends FormalEngineAnnotation

case object PonoEngineAnnotation extends FormalEngineAnnotation

/** Formal Verification based on the firrtl compiler's SMT backend and the maltese SMT libraries solver bindings. */
private[chiseltest] object Maltese {
def bmc(circuit: ir.Circuit, annos: AnnotationSeq, kMax: Int, resetLength: Int = 0): Unit = {
Expand Down Expand Up @@ -166,10 +168,11 @@ private[chiseltest] object Maltese {
engines.map {
case CVC4EngineAnnotation => new SMTModelChecker(CVC4SMTLib)
case Z3EngineAnnotation => new SMTModelChecker(Z3SMTLib)
case BtormcEngineAnnotation => new BtormcModelChecker(targetDir)
case BtormcEngineAnnotation => new Btor2ModelChecker(BtormcBtor2, targetDir)
case Yices2EngineAnnotation => new SMTModelChecker(Yices2SMTLib)
case BoolectorEngineAnnotation => new SMTModelChecker(BoolectorSMTLib)
case BitwuzlaEngineAnnotation => new SMTModelChecker(BitwuzlaSMTLib)
case PonoEngineAnnotation => new Btor2ModelChecker(PonoBtor2, targetDir)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,25 @@ package chiseltest.formal.backends.btor
import chiseltest.formal.backends._
import firrtl2.backends.experimental.smt._

class BtormcModelChecker(targetDir: os.Path) extends IsModelChecker {
private[chiseltest] trait Solver {
def cmd(btorFile: String, kMax: Int): Seq[String]
}

object BtormcBtor2 extends Solver {
override def cmd(btorFile: String, kMax: Int): Seq[String] = {
val kmaxOpt = if (kMax > 0) Seq("--kmax", kMax.toString) else Seq()
Seq("btormc") ++ kmaxOpt ++ Seq(btorFile)
}
}

object PonoBtor2 extends Solver {
override def cmd(btorFile: String, kMax: Int): Seq[String] = {
val kmaxOpt = if (kMax > 0) Seq("-k", kMax.toString) else Seq()
Seq("pono") ++ Seq("-e", "bmc") ++ kmaxOpt ++ Seq("--vcd", "ignore.vcd") ++ Seq(btorFile)
}
}

class Btor2ModelChecker(solver: Solver, targetDir: os.Path) extends IsModelChecker {
override val fileExtension = ".btor2"
override val name: String = "btormc"
override val prefix: String = "btormc"
Expand All @@ -18,8 +36,7 @@ class BtormcModelChecker(targetDir: os.Path) extends IsModelChecker {
os.write.over(targetDir / filename, lines.mkString("", "\n", "\n"))

// execute model checker
val kmaxOpt = if (kMax > 0) Seq("--kmax", kMax.toString) else Seq()
val cmd = Seq("btormc") ++ kmaxOpt ++ Seq(filename)
val cmd = solver.cmd(filename, kMax)
val r = os.proc(cmd).call(cwd = targetDir, check = false)

// write stdout to file for debugging
Expand All @@ -32,15 +49,13 @@ class BtormcModelChecker(targetDir: os.Path) extends IsModelChecker {

if (isSat) {
val witness = Btor2WitnessParser.read(res, 1).head
ModelCheckFail(Btor2ModelChecker.convertWitness(sys, witness))
ModelCheckFail(convertWitness(sys, witness))
} else {
ModelCheckSuccess()
}
}
}

object Btor2ModelChecker {
def convertWitness(sys: TransitionSystem, bw: Btor2Witness): Witness = {
private def convertWitness(sys: TransitionSystem, bw: Btor2Witness): Witness = {
val badNames = sys.signals.filter(_.lbl == IsBad).map(_.name).toIndexedSeq
val failed = bw.failed.map(badNames)
Witness(failed, bw.regInit, bw.memInit, bw.inputs)
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/chiseltest/formal/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ package object formal {
val Z3EngineAnnotation = backends.Z3EngineAnnotation
val BtormcEngineAnnotation = backends.BtormcEngineAnnotation
val BitwuzlaEngineAnnotation = backends.BitwuzlaEngineAnnotation
val PonoEngineAnnotation = backends.PonoEngineAnnotation
val MagicPacketTracker = vips.MagicPacketTracker
}
1 change: 1 addition & 0 deletions src/test/scala/chiseltest/formal/FormalBackendOption.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ object FormalBackendOption {
case Some("z3") => Z3EngineAnnotation
case Some("cvc4") => CVC4EngineAnnotation
case Some("btormc") => BtormcEngineAnnotation
case Some("pono") => PonoEngineAnnotation
case Some("yices2") => throw new RuntimeException("yices is not supported yet")
case Some("boolector") => throw new RuntimeException("boolector is not supported yet")
case Some("bitwuzla") => BitwuzlaEngineAnnotation
Expand Down

0 comments on commit 74365bb

Please sign in to comment.