Merge pull request #147 from jix/smtbmc-keepgoing
authorJannis Harder <me@jix.one>
Wed, 30 Mar 2022 09:42:48 +0000 (11:42 +0200)
committerGitHub <noreply@github.com>
Wed, 30 Mar 2022 09:42:48 +0000 (11:42 +0200)
Support and tests for smtbmc `--keep-going`

docs/source/reference.rst
sbysrc/sby_core.py
sbysrc/sby_design.py
sbysrc/sby_engine_smtbmc.py
tests/.gitignore
tests/2props1trace.sby [new file with mode: 0644]
tests/aim_vs_smt2_nonzero_start_offset.sby [new file with mode: 0644]
tests/submod_props.sby

index dc5f33631936e24b5c771bcbce5075c6a635c326..9cbf78bccb8b45adc10a054bfcfdbca4dce8967b 100644 (file)
@@ -120,10 +120,12 @@ Mode      Description
 ``prove`` Unbounded model check to verify safety properties (``assert(...)`` statements)
 ``live``  Unbounded model check to verify liveness properties (``assert(s_eventually ...)`` statements)
 ``cover`` Generate set of shortest traces required to reach all cover() statements
-``equiv`` Formal equivalence checking (usually to verify pre- and post-synthesis equivalence)
-``synth`` Reactive Synthesis (synthesis of circuit from safety properties)
 ========= ===========
 
+..
+   ``equiv`` Formal equivalence checking (usually to verify pre- and post-synthesis equivalence)
+   ``synth`` Reactive Synthesis (synthesis of circuit from safety properties)
+
 All other options have default values and thus are optional. The available
 options are:
 
@@ -197,6 +199,38 @@ solver options.
 In the 2nd line ``abc`` is the engine, there are no engine options, ``sim3`` is the
 solver, and ``-W 15`` are solver options.
 
+The following mode/engine/solver combinations are currently supported:
+
++-----------+--------------------------+
+| Mode      | Engine                   |
++===========+==========================+
+| ``bmc``   | ``smtbmc [all solvers]`` |
+|           |                          |
+|           | ``btor btormc``          |
+|           |                          |
+|           | ``btor pono``            |
+|           |                          |
+|           | ``abc bmc3``             |
+|           |                          |
+|           | ``abc sim3``             |
++-----------+--------------------------+
+| ``prove`` | ``smtbmc [all solvers]`` |
+|           |                          |
+|           | ``abc pdr``              |
+|           |                          |
+|           | ``aiger avy``            |
+|           |                          |
+|           | ``aiger suprove``        |
++-----------+--------------------------+
+| ``cover`` | ``smtbmc [all solvers]`` |
+|           |                          |
+|           | ``btor btormc``          |
++-----------+--------------------------+
+| ``live``  | ``aiger suprove``        |
+|           |                          |
+|           | ``aiger avy``            |
++-----------+--------------------------+
+
 ``smtbmc`` engine
 ~~~~~~~~~~~~~~~~~
 
@@ -240,12 +274,28 @@ The following solvers are currently supported by ``yosys-smtbmc``:
 
   * yices
   * boolector
+  * bitwuzla
   * z3
   * mathsat
   * cvc4
 
 Any additional options after ``--`` are passed to ``yosys-smtbmc`` as-is.
 
+``btor`` engine
+~~~~~~~~~~~~~~~
+
+The ``btor`` engine supports hardware modelcheckers that accept btor2 files.
+The engine supports no engine options and supports the following solvers:
+
++-------------------------------+---------------------------------+
+|   Solver                      |   Modes                         |
++===============================+=================================+
+| ``btormc``                    |   ``bmc``, ``cover``            |
++-------------------------------+---------------------------------+
+| ``pono``                      |   ``bmc``                       |
++-------------------------------+---------------------------------+
+
+
 ``aiger`` engine
 ~~~~~~~~~~~~~~~~
 
index e1ee51c363f38b37175bfd4e71243745feea8faf..b78ef8531d24547d0c022319fa6f8ec6d784dbe4 100644 (file)
@@ -503,7 +503,7 @@ class SbyTask:
                 print("abc -g AND -fast", file=f)
                 print("opt_clean", file=f)
                 print("stat", file=f)
-                print("write_aiger -I -B -zinit -map design_aiger.aim design_aiger.aig", file=f)
+                print("write_aiger -I -B -zinit -no-startoffset -map design_aiger.aim design_aiger.aig", file=f)
 
             proc = SbyProc(
                 self,
index 98a57f132b16c1c733c1234ace39b1e1f450d312..6dfbaecb9dd9dab6dee8975ceb9bd7e85ccb2666 100644 (file)
@@ -91,11 +91,13 @@ class SbyModule:
             raise KeyError(f"Could not find assert at {location} in properties list!")
         return prop
 
-    def find_property_by_cellname(self, cell_name):
+    def find_property_by_cellname(self, cell_name, trans_dict=dict()):
+        # backends may need to mangle names irreversibly, so allow applying
+        # the same transformation here
         for prop in self:
-            if prop.name == cell_name:
+            if cell_name == prop.name.translate(str.maketrans(trans_dict)):
                 return prop
-        raise KeyError(f"No such property: {cell_name}")
+        raise KeyError(f"No such property: {smt2_name}")
 
 def design_hierarchy(filename):
     design_json = json.load(filename)
index 9b7ff2b8695921425e4892613d847719c67ee2c6..18cfb092e5a273740860761a2c064baa63ef754f 100644 (file)
@@ -164,11 +164,12 @@ def run(mode, task, engine_idx, engine):
         task.induction_procs.append(proc)
 
     proc_status = None
-    last_prop = None
+    last_prop = []
 
     def output_callback(line):
         nonlocal proc_status
         nonlocal last_prop
+        smt2_trans = {'\\':'/', '|':'/'}
 
         match = re.match(r"^## [0-9: ]+ Status: FAILED", line)
         if match:
@@ -193,29 +194,30 @@ def run(mode, task, engine_idx, engine):
         match = re.match(r"^## [0-9: ]+ Assert failed in (\S+): (\S+) \((\S+)\)", line)
         if match:
             cell_name = match[3]
-            prop = task.design_hierarchy.find_property_by_cellname(cell_name)
+            prop = task.design_hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans)
             prop.status = "FAIL"
-            last_prop = prop
+            last_prop.append(prop)
             return line
 
         match = re.match(r"^## [0-9: ]+ Reached cover statement at (\S+) \((\S+)\) in step \d+.", line)
         if match:
             cell_name = match[2]
-            prop = task.design_hierarchy.find_property_by_cellname(cell_name)
+            prop = task.design_hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans)
             prop.status = "PASS"
-            last_prop = prop
+            last_prop.append(prop)
             return line
 
         match = re.match(r"^## [0-9: ]+ Writing trace to VCD file: (\S+)", line)
         if match and last_prop:
-            last_prop.tracefile = match[1]
-            last_prop = None
+            for p in last_prop:
+                p.tracefile = match[1]
+            last_prop = []
             return line
 
         match = re.match(r"^## [0-9: ]+ Unreached cover statement at (\S+) \((\S+)\).", line)
         if match:
             cell_name = match[2]
-            prop = task.design_hierarchy.find_property_by_cellname(cell_name)
+            prop = task.design_hierarchy.find_property_by_cellname(cell_name, trans_dict=smt2_trans)
             prop.status = "FAIL"
 
         return line
index 86d3851aaf89cdb7e4f1dad49f9beff9dee019f6..23d000849d886622aefc2e48115fb37ed990da18 100644 (file)
@@ -11,3 +11,4 @@
 /keepgoing_*/
 /submod_props*/
 /multi_assert*/
+/aim_vs_smt2_nonzero_start_offset*/
diff --git a/tests/2props1trace.sby b/tests/2props1trace.sby
new file mode 100644 (file)
index 0000000..8f51fde
--- /dev/null
@@ -0,0 +1,22 @@
+[options]
+mode bmc
+depth 1
+expect fail
+
+[engines]
+smtbmc
+
+[script]
+read -sv top.sv
+prep -top top
+
+[file top.sv]
+module top(
+input foo,
+input bar
+);
+always @(*) begin
+       assert (foo);
+       assert (bar);
+end
+endmodule
diff --git a/tests/aim_vs_smt2_nonzero_start_offset.sby b/tests/aim_vs_smt2_nonzero_start_offset.sby
new file mode 100644 (file)
index 0000000..4309551
--- /dev/null
@@ -0,0 +1,33 @@
+[tasks]
+bmc
+prove
+
+[options]
+bmc: mode bmc
+prove: mode prove
+expect fail
+wait on
+
+[engines]
+bmc: abc bmc3
+bmc: abc sim3
+prove: aiger avy
+prove: aiger suprove
+prove: abc pdr
+
+[script]
+read -sv test.sv
+prep -top test
+
+[file test.sv]
+module test (
+    input clk,
+    input [8:1] nonzero_offset
+);
+    reg [7:0] counter = 0;
+
+    always @(posedge clk) begin
+        if (counter == 3) assert(nonzero_offset[1]);
+        counter <= counter + 1;
+    end
+endmodule
index 93abc9c139d18ca8d8fe07d943e7f63acec99fec..99336767d86772ce4b8452ec1df50935e55950c6 100644 (file)
@@ -1,10 +1,12 @@
 [tasks]
 bmc
 cover
+flatten
 
 [options]
 bmc: mode bmc
 cover: mode cover
+flatten: mode bmc
 
 expect fail
 
@@ -14,6 +16,7 @@ smtbmc boolector
 [script]
 read -sv test.sv
 prep -top top
+flatten: flatten
 
 [file test.sv]
 module test(input foo);