diff options
| author | Tom Alcorn | 2020-06-23 13:12:05 -0700 |
|---|---|---|
| committer | GitHub | 2020-06-23 13:12:05 -0700 |
| commit | 8322316a2f7c7fe7dad72f413e75d6b4600823f0 (patch) | |
| tree | db69527225ce78a9c33be6844c7836428d1f3af7 /src/main/scala/firrtl/ir | |
| parent | d1db9067309fe2d7765def39ac4085edfe53d7be (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.scala | 32 |
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 |
