You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adjust the syntax of the `formal` declaration to no longer expect a
single fixed `bound = <N>` parameter, but instead accept a list of
user-defined parameters similar to an `extmodule`. The parameters can be
integers, strings, arrays, and dictionaries. They are passed through to
the tooling running the formal test. As we build out that tooling, we
may standardize some of the parameters.
Marking this as "major" since it technically is a breaking change, but
in practice there are no users of `formal` as of today and the original
syntax has never been released as part of the spec.
Copy file name to clipboardExpand all lines: spec.md
+50-40Lines changed: 50 additions & 40 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -286,61 +286,63 @@ circuit Foo :
286
286
public module Foo enablelayer A :
287
287
```
288
288
289
-
## Formal Tests
289
+
## Formal Unit Tests
290
290
291
-
Formal tests are named top-level constructs which allow for formal test harnesses to be definied
292
-
as bounded model checking (BMC) problems. The body of the formal test harness is converted
293
-
into a BMC formula which encodes a state-transition system version of the design using one
294
-
of the formal backends (targetting either BTOR2 or SMTLib).
295
-
Formal tests have 3 operands:
291
+
The `formal`{.firrtl} keyword declares a formal unit test.
292
+
Tools may look for these constructs and automatically run them as part of a regression test suite.
296
293
297
-
1. A name that the test can be referred to with.
298
-
2. The name of the formal test harness module.
299
-
3. A positive integer bound for the test. This number indicates the depth to which the model will be checked.
294
+
A formal unit test has a unique name and refers to a module declaration that contains the design to be verified and any necessary test harness.
295
+
Additionally, the test may also declare a list of user-defined named parameters which can be integers, strings, arrays, or dictionaries.
296
+
These parameters are passed on to any tools that execute the tests.
297
+
No parameters with well-known semantics are defined yet.
298
+
During execution of the formal test, all input ports of the target module are treated as symbolic values that may change in every cycle.
299
+
All output ports are ignored.
300
300
301
-
```firrtl
301
+
The circuit below shows a module run as a formal unit test:
302
+
303
+
```{.firrtl .notest}
302
304
FIRRTL version 4.0.0
303
305
circuit Foo :
304
306
public module Foo :
305
-
; ...
306
-
formal testFoo of Foo, bound = 20
307
+
formal myTest of Foo :
307
308
```
308
309
309
-
More details about how bounded model checking works and what the bound refers to can be found in
310
-
[Biere et al. 2003](https://doi.org/10.1016/S0065-2458(03)58003-2).
310
+
A module may be reused in multiple unit tests, for example to run with different testing parameters:
311
311
312
-
### Formal Test Harness
312
+
```{.firrtl .notest}
313
+
FIRRTL version 4.0.0
314
+
circuit Foo :
315
+
public module Foo :
316
+
formal myTestA of Foo :
317
+
mode = "bmc"
318
+
bound = 42
319
+
formal myTestB of Foo :
320
+
mode = "induction"
321
+
bound = 100
322
+
```
313
323
314
-
A public module definition may be used as a formal test harness.
315
-
Their input ports act as symbolic variables for the test.
324
+
### Test Harnesses
316
325
317
-
Example:
326
+
It may be necessary to define additional verification constructs and hardware in addition to the design that should be run in a formal unit test.
327
+
To achieve this, an additional module may act as a test harness and instantiate the design to be tested alongside any other necessary verification collateral:
318
328
319
-
```firrtl
329
+
```{.firrtl .notest}
320
330
FIRRTL version 4.0.0
331
+
circuit Foo :
332
+
public module Foo :
333
+
input a : UInt<42>
334
+
output b : UInt<42>
335
+
; ...
321
336
322
-
circuit Foo:
323
-
public module Foo:
324
-
input data : UInt<32>
325
-
input c : UInt<1>
326
-
output out : UInt<32>
327
-
;; Foo body
328
-
329
-
public module FooTest:
330
-
;; symbolic input -- maps to input in btor2
331
-
input s_foo_c : UInt<1>
332
-
input s_foo_data : UInt<32>
333
-
;; example test
337
+
public module FooTest :
338
+
input clk : Clock
339
+
input a : UInt<42>
334
340
inst foo of Foo
335
-
;; feed the symbolic inputs to the instance
336
-
connect foo.c, s_foo_c
337
-
connect foo.data, s_foo_data
338
-
;; example assertion that uses the symbolic inputs and outputs
0 commit comments