aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/ir
diff options
context:
space:
mode:
authorTom Alcorn2020-06-23 13:12:05 -0700
committerGitHub2020-06-23 13:12:05 -0700
commit8322316a2f7c7fe7dad72f413e75d6b4600823f0 (patch)
treedb69527225ce78a9c33be6844c7836428d1f3af7 /src/main/scala/firrtl/ir
parentd1db9067309fe2d7765def39ac4085edfe53d7be (diff)
Basic model checking API (#1653)
* Add assume, assert, cover statements * Assert submodule assumptions * Add warning when removing verification statements * Remove System Verilog behaviour emitter warning * Add option to disable AssertSubmoduleAssumptions * Document verification statements in the spec The syntax for the new statements is assert(clk, cond, en, msg) assume(clk, cond, en, msg) cover(clk, cond, en, msg) With assert as a representative example, the semantics is as follows: `clk` is the clock, `cond` is the expression being asserted, `en` is the enable signal (if `en` is low then the assert is not checked) and `msg` is a string message intended to be reported as an error message by the model checker if the assertion fails. In the Verilog emitter, the new statements are handled by a new `formals` map, which groups the statements by clock domain. All model checking statements are then emitted within the context of an `ifdef FORMAL` block, which allows model checking tools (like Symbiyosys) to utilize the statements while keeping them out of synthesis flows. Co-authored-by: Albert Magyar <albert.magyar@gmail.com>
Diffstat (limited to 'src/main/scala/firrtl/ir')
-rw-r--r--src/main/scala/firrtl/ir/IR.scala32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/ir/IR.scala b/src/main/scala/firrtl/ir/IR.scala
index a47a4cea..9914ad45 100644
--- a/src/main/scala/firrtl/ir/IR.scala
+++ b/src/main/scala/firrtl/ir/IR.scala
@@ -541,6 +541,38 @@ case class Print(
def foreachString(f: String => Unit): Unit = Unit
def foreachInfo(f: Info => Unit): Unit = f(info)
}
+
+// formal
+object Formal extends Enumeration {
+ val Assert = Value("assert")
+ val Assume = Value("assume")
+ val Cover = Value("cover")
+}
+
+case class Verification(
+ op: Formal.Value,
+ info: Info,
+ clk: Expression,
+ pred: Expression,
+ en: Expression,
+ msg: StringLit
+) extends Statement with HasInfo {
+ def serialize: String = op + "(" + Seq(clk, pred, en).map(_.serialize)
+ .mkString(", ") + ", \"" + msg.serialize + "\")" + info.serialize
+ def mapStmt(f: Statement => Statement): Statement = this
+ def mapExpr(f: Expression => Expression): Statement =
+ copy(clk = f(clk), pred = f(pred), en = f(en))
+ def mapType(f: Type => Type): Statement = this
+ def mapString(f: String => String): Statement = this
+ def mapInfo(f: Info => Info): Statement = copy(info = f(info))
+ def foreachStmt(f: Statement => Unit): Unit = Unit
+ def foreachExpr(f: Expression => Unit): Unit = { f(clk); f(pred); f(en); }
+ def foreachType(f: Type => Unit): Unit = Unit
+ def foreachString(f: String => Unit): Unit = Unit
+ def foreachInfo(f: Info => Unit): Unit = f(info)
+}
+// end formal
+
case object EmptyStmt extends Statement {
def serialize: String = "skip"
def mapStmt(f: Statement => Statement): Statement = this