Improvements in yosys-smtbmc

This commit is contained in:
Clifford Wolf 2015-10-14 01:27:55 +02:00
parent 821f1b8534
commit d7de0f4bd1
3 changed files with 38 additions and 21 deletions

View File

@ -5,11 +5,10 @@ ifneq ($(CONFIG),mxe)
ifneq ($(CONFIG),emcc) ifneq ($(CONFIG),emcc)
TARGETS += yosys-smtbmc TARGETS += yosys-smtbmc
yosys-smtbmc: yosys-smtbmc: backends/smt2/smtbmc.py
$(P) sed '3 { p; s|.*|sys.path += [os.path.dirname(__file__) + p for p in ["/share/python3", "/../share/yosys/python3"]]|; }' \ $(P) sed '3 { p; s|.*|sys.path += [os.path.dirname(__file__) + p for p in ["/share/python3", "/../share/yosys/python3"]]|; }' < $< > $@.new
< backends/smt2/smtbmc.py > yosys-smtbmc.new $(Q) chmod +x $@.new
$(Q) chmod +x yosys-smtbmc.new $(Q) mv $@.new $@
$(Q) mv yosys-smtbmc.new yosys-smtbmc
$(eval $(call add_share_file,share/python3,backends/smt2/smtio.py)) $(eval $(call add_share_file,share/python3,backends/smt2/smtio.py))
endif endif

View File

@ -3,10 +3,11 @@
import os, sys, getopt, re import os, sys, getopt, re
from smtio import smtio, smtopts, mkvcd from smtio import smtio, smtopts, mkvcd
max_steps = 20 skip_steps = 0
min_steps = None num_steps = 20
vcdfile = None vcdfile = None
tempind = False tempind = False
assume_skipped = None
topmod = "main" topmod = "main"
so = smtopts() so = smtopts()
@ -15,15 +16,18 @@ def usage():
print(""" print("""
yosys-smtbmc [options] <yosys_smt2_output> yosys-smtbmc [options] <yosys_smt2_output>
-t <max_steps> -t <num_steps>, -t <skip_steps>:<num_steps>
default: 20 default: skip_steps=0, num_steps=20
-u <start_step>
assume asserts in skipped steps in BMC
-c <vcd_filename> -c <vcd_filename>
write counter-example to this VCD file write counter-example to this VCD file
(hint: use 'write_smt2 -wires' for maximum (hint: use 'write_smt2 -wires' for maximum
coverage of signals in generated VCD file) coverage of signals in generated VCD file)
-i <min_steps> -i
instead of BMC run temporal induction instead of BMC run temporal induction
-m <module_name> -m <module_name>
@ -33,18 +37,24 @@ yosys-smtbmc [options] <yosys_smt2_output>
try: try:
opts, args = getopt.getopt(sys.argv[1:], so.optstr + "t:c:i:m:") opts, args = getopt.getopt(sys.argv[1:], so.optstr + "t:u:c:im:")
except: except:
usage() usage()
for o, a in opts: for o, a in opts:
if o == "-t": if o == "-t":
max_steps = int(a) match = re.match(r"(\d+):(.*)", a)
if match:
skip_steps = int(match.group(1))
num_steps = int(match.group(2))
else:
num_steps = int(a)
elif o == "-u":
assume_skipped = int(a)
elif o == "-c": elif o == "-c":
vcdfile = a vcdfile = a
elif o == "-i": elif o == "-i":
tempind = True tempind = True
min_steps = int(a)
elif o == "-m": elif o == "-m":
topmod = a topmod = a
elif so.handle(o, a): elif so.handle(o, a):
@ -58,7 +68,7 @@ if len(args) != 1:
smt = smtio(opts=so) smt = smtio(opts=so)
print("Solver: %s" % so.solver) print("%s Solver: %s" % (smt.timestamp(), so.solver))
smt.setup("QF_AUFBV") smt.setup("QF_AUFBV")
debug_nets = set() debug_nets = set()
@ -89,18 +99,18 @@ def write_vcd_model():
if tempind: if tempind:
for step in range(max_steps, -1, -1): for step in range(num_steps, -1, -1):
smt.write("(declare-fun s%d () %s_s)" % (step, topmod)) smt.write("(declare-fun s%d () %s_s)" % (step, topmod))
smt.write("(assert (%s_u s%d))" % (topmod, step)) smt.write("(assert (%s_u s%d))" % (topmod, step))
if step == max_steps: if step == num_steps:
smt.write("(assert (not (%s_a s%d)))" % (topmod, step)) smt.write("(assert (not (%s_a s%d)))" % (topmod, step))
else: else:
smt.write("(assert (%s_t s%d s%d))" % (topmod, step, step+1)) smt.write("(assert (%s_t s%d s%d))" % (topmod, step, step+1))
smt.write("(assert (%s_a s%d))" % (topmod, step)) smt.write("(assert (%s_a s%d))" % (topmod, step))
if step > max_steps-min_steps: if step > num_steps-skip_steps:
print("%s Skipping induction in step %d.." % (smt.timestamp(), step)) print("%s Skipping induction in step %d.." % (smt.timestamp(), step))
continue continue
@ -118,7 +128,7 @@ if tempind:
else: # not tempind else: # not tempind
for step in range(max_steps+1): for step in range(num_steps+1):
smt.write("(declare-fun s%d () %s_s)" % (step, topmod)) smt.write("(declare-fun s%d () %s_s)" % (step, topmod))
smt.write("(assert (%s_u s%d))" % (topmod, step)) smt.write("(assert (%s_u s%d))" % (topmod, step))
@ -128,6 +138,14 @@ else: # not tempind
else: else:
smt.write("(assert (%s_t s%d s%d))" % (topmod, step-1, step)) smt.write("(assert (%s_t s%d s%d))" % (topmod, step-1, step))
if step < skip_steps:
if assume_skipped is not None and step >= assume_skipped:
print("%s Skipping step %d (and assuming pass).." % (smt.timestamp(), step))
smt.write("(assert (%s_a s%d))" % (topmod, step))
else:
print("%s Skipping step %d.." % (smt.timestamp(), step))
continue
print("%s Checking asserts in step %d.." % (smt.timestamp(), step)) print("%s Checking asserts in step %d.." % (smt.timestamp(), step))
smt.write("(push 1)") smt.write("(push 1)")

View File

@ -55,7 +55,7 @@ class smtio:
def timestamp(self): def timestamp(self):
secs = int(time() - self.start_time) secs = int(time() - self.start_time)
return "+ %6d %3d:%02d:%02d " % (secs, secs // (60*60), (secs // 60) % 60, secs % 60) return "## %6d %3d:%02d:%02d " % (secs, secs // (60*60), (secs // 60) % 60, secs % 60)
def write(self, stmt): def write(self, stmt):
stmt = stmt.strip() stmt = stmt.strip()