mirror of
https://github.com/YosysHQ/sby.git
synced 2025-07-29 17:38:01 +00:00
Unified trace generation using yosys's sim across all engines
Currently opt-in using the `fst` or `vcd_sim` options.
This commit is contained in:
parent
4c44a10f72
commit
6d3b5aa960
15 changed files with 686 additions and 183 deletions
|
@ -18,6 +18,7 @@
|
|||
|
||||
import re, os, getopt, click
|
||||
from sby_core import SbyProc
|
||||
from sby_sim import sim_witness_trace
|
||||
|
||||
def run(mode, task, engine_idx, engine):
|
||||
opts, solver_args = getopt.getopt(engine[1:], "", [])
|
||||
|
@ -51,6 +52,22 @@ def run(mode, task, engine_idx, engine):
|
|||
else:
|
||||
task.error(f"Invalid solver command {solver_args[0]}.")
|
||||
|
||||
smtbmc_vcd = task.opt_vcd and not task.opt_vcd_sim
|
||||
run_aigsmt = (mode != "live") and (smtbmc_vcd or (task.opt_append and task.opt_append_assume))
|
||||
smtbmc_append = 0
|
||||
sim_append = 0
|
||||
log = task.log_prefix(f"engine_{engine_idx}")
|
||||
|
||||
if mode != "live":
|
||||
if task.opt_append_assume:
|
||||
smtbmc_append = task.opt_append
|
||||
elif smtbmc_vcd:
|
||||
if not task.opt_append_assume:
|
||||
log("For VCDs generated by smtbmc the option 'append_assume off' is ignored")
|
||||
smtbmc_append = task.opt_append
|
||||
else:
|
||||
sim_append = task.opt_append
|
||||
|
||||
proc = SbyProc(
|
||||
task,
|
||||
f"engine_{engine_idx}",
|
||||
|
@ -92,44 +109,48 @@ def run(mode, task, engine_idx, engine):
|
|||
return None
|
||||
|
||||
def exit_callback(retcode):
|
||||
aiw_file.close()
|
||||
aigsmt_exit_callback(task, engine_idx, proc_status,
|
||||
run_aigsmt=run_aigsmt, smtbmc_vcd=smtbmc_vcd, smtbmc_append=smtbmc_append, sim_append=sim_append, )
|
||||
|
||||
proc.output_callback = output_callback
|
||||
proc.register_exit_callback(exit_callback)
|
||||
|
||||
|
||||
def aigsmt_exit_callback(task, engine_idx, proc_status, *, run_aigsmt, smtbmc_vcd, smtbmc_append, sim_append):
|
||||
if proc_status is None:
|
||||
task.error(f"engine_{engine_idx}: Could not determine engine status.")
|
||||
|
||||
aiw_file.close()
|
||||
|
||||
task.update_status(proc_status)
|
||||
task.log(f"{click.style(f'engine_{engine_idx}', fg='magenta')}: Status returned by engine: {proc_status}")
|
||||
task.summary.append(f"""engine_{engine_idx} ({" ".join(engine)}) returned {proc_status}""")
|
||||
|
||||
task.summary.set_engine_status(engine_idx, proc_status)
|
||||
task.terminate()
|
||||
|
||||
if proc_status == "FAIL" and task.opt_aigsmt != "none":
|
||||
if produced_cex:
|
||||
trace_prefix = f"engine_{engine_idx}/trace"
|
||||
if proc_status == "FAIL" and (not run_aigsmt or task.opt_aigsmt != "none"):
|
||||
trace_prefix = f"engine_{engine_idx}/trace"
|
||||
|
||||
aiw2yw_suffix = '_aiw' if run_aigsmt else ''
|
||||
|
||||
witness_proc = SbyProc(
|
||||
task, f"engine_{engine_idx}", [],
|
||||
f"cd {task.workdir}; {task.exe_paths['witness']} aiw2yw engine_{engine_idx}/trace.aiw model/design_aiger.ywa engine_{engine_idx}/trace{aiw2yw_suffix}.yw",
|
||||
)
|
||||
yw_proc = witness_proc
|
||||
|
||||
if run_aigsmt:
|
||||
smtbmc_opts = []
|
||||
if mode == "live":
|
||||
smtbmc_opts += ["-g"]
|
||||
smtbmc_opts += ["-s", task.opt_aigsmt]
|
||||
if task.opt_tbtop is not None:
|
||||
smtbmc_opts += ["--vlogtb-top", task.opt_tbtop]
|
||||
smtbmc_opts += ["--noprogress"]
|
||||
if mode != "live":
|
||||
smtbmc_opts += [f"--append {task.opt_append}"]
|
||||
if task.opt_vcd:
|
||||
smtbmc_opts += ["--noprogress", f"--append {smtbmc_append}"]
|
||||
if smtbmc_vcd:
|
||||
smtbmc_opts += [f"--dump-vcd {trace_prefix}.vcd"]
|
||||
smtbmc_opts += [f"--dump-yw {trace_prefix}.yw", f"--dump-vlogtb {trace_prefix}_tb.v", f"--dump-smtc {trace_prefix}.smtc"]
|
||||
|
||||
witness_proc = SbyProc(
|
||||
task, f"engine_{engine_idx}", [],
|
||||
f"cd {task.workdir}; {task.exe_paths['witness']} aiw2yw engine_{engine_idx}/trace.aiw model/design_aiger.ywa engine_{engine_idx}/trace.yw",
|
||||
)
|
||||
|
||||
proc2 = SbyProc(
|
||||
task,
|
||||
f"engine_{engine_idx}",
|
||||
[*task.model("smt2"), witness_proc],
|
||||
f"cd {task.workdir}; {task.exe_paths['smtbmc']} {' '.join(smtbmc_opts)} --yw engine_{engine_idx}/trace.yw model/design_smt2.smt2",
|
||||
f"cd {task.workdir}; {task.exe_paths['smtbmc']} {' '.join(smtbmc_opts)} --yw engine_{engine_idx}/trace{aiw2yw_suffix}.yw model/design_smt2.smt2",
|
||||
logfile=open(f"{task.workdir}/engine_{engine_idx}/logfile2.txt", "w")
|
||||
)
|
||||
|
||||
|
@ -146,20 +167,21 @@ def run(mode, task, engine_idx, engine):
|
|||
|
||||
return line
|
||||
|
||||
def exit_callback2(line):
|
||||
def exit_callback2(retcode):
|
||||
if proc2_status is None:
|
||||
task.error(f"engine_{engine_idx}: Could not determine aigsmt status.")
|
||||
if proc2_status != ("PASS" if mode == "live" else "FAIL"):
|
||||
if proc2_status != "FAIL":
|
||||
task.error(f"engine_{engine_idx}: Unexpected aigsmt status.")
|
||||
|
||||
if os.path.exists(f"{task.workdir}/engine_{engine_idx}/trace.vcd"):
|
||||
task.summary.append(f"counterexample trace: {task.workdir}/engine_{engine_idx}/trace.vcd")
|
||||
task.summary.add_event(engine_idx, trace="trace", path=f"engine_{engine_idx}/trace.vcd", type="$assert")
|
||||
|
||||
proc2.output_callback = output_callback2
|
||||
proc2.exit_callback = exit_callback2
|
||||
proc2.register_exit_callback(exit_callback2)
|
||||
|
||||
yw_proc = proc2
|
||||
|
||||
if task.opt_fst or (task.opt_vcd and task.opt_vcd_sim):
|
||||
sim_witness_trace(f"engine_{engine_idx}", task, engine_idx, f"engine_{engine_idx}/trace.yw", append=sim_append, deps=[yw_proc])
|
||||
|
||||
else:
|
||||
task.log(f"{click.style(f'engine_{engine_idx}', fg='magenta')}: Engine did not produce a counter example.")
|
||||
|
||||
proc.output_callback = output_callback
|
||||
proc.exit_callback = exit_callback
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue