mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-30 07:53:16 +00:00
smtbmc: Add native json based witness format + smt2 backend support
This adds a native json based witness trace format. By having a common format that includes everything we support, and providing a conversion utility (yosys-witness) we no longer need to implement every format for every tool that deals with witness traces, avoiding a quadratic opportunity to introduce subtle bugs. Included: * smt2: New yosys-smt2-witness info lines containing full hierarchical paths without lossy escaping. * yosys-smtbmc --dump-yw trace.yw: Dump results in the new format. * yosys-smtbmc --yw trace.yw: Read new format as constraints. * yosys-witness: New tool to convert witness formats. Currently this can only display traces in a human-readable-only format and do a passthrough read/write of the new format. * ywio.py: Small python lib for reading and writing the new format. Used by yosys-smtbmc and yosys-witness to avoid duplication.
This commit is contained in:
parent
96a1173598
commit
f041e36c6e
9 changed files with 983 additions and 113 deletions
|
@ -16,7 +16,7 @@
|
|||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
import sys, re, os, signal
|
||||
import sys, re, os, signal, json
|
||||
import subprocess
|
||||
if os.name == "posix":
|
||||
import resource
|
||||
|
@ -108,6 +108,7 @@ class SmtModInfo:
|
|||
self.allconsts = dict()
|
||||
self.allseqs = dict()
|
||||
self.asize = dict()
|
||||
self.witness = []
|
||||
|
||||
|
||||
class SmtIo:
|
||||
|
@ -587,6 +588,11 @@ class SmtIo:
|
|||
self.modinfo[self.curmod].allseqs[fields[2]] = (fields[4], None if len(fields) <= 5 else fields[5])
|
||||
self.modinfo[self.curmod].asize[fields[2]] = int(fields[3])
|
||||
|
||||
if fields[1] == "yosys-smt2-witness":
|
||||
data = json.loads(stmt.split(None, 2)[2])
|
||||
if data.get("type") in ["cell", "mem", "posedge", "negedge", "input", "reg", "init", "seq", "blackbox"]:
|
||||
self.modinfo[self.curmod].witness.append(data)
|
||||
|
||||
def hiernets(self, top, regs_only=False):
|
||||
def hiernets_worker(nets, mod, cursor):
|
||||
for netname in sorted(self.modinfo[mod].wsize.keys()):
|
||||
|
@ -658,6 +664,57 @@ class SmtIo:
|
|||
hiermems_worker(mems, top, [])
|
||||
return mems
|
||||
|
||||
def hierwitness(self, top, allregs=False, blackbox=True):
|
||||
init_witnesses = []
|
||||
seq_witnesses = []
|
||||
clk_witnesses = []
|
||||
mem_witnesses = []
|
||||
|
||||
def absolute(path, cursor, witness):
|
||||
return {
|
||||
**witness,
|
||||
"path": path + tuple(witness["path"]),
|
||||
"smtpath": cursor + [witness["smtname"]],
|
||||
}
|
||||
|
||||
for witness in self.modinfo[top].witness:
|
||||
if witness["type"] == "input":
|
||||
seq_witnesses.append(absolute((), [], witness))
|
||||
if witness["type"] in ("posedge", "negedge"):
|
||||
clk_witnesses.append(absolute((), [], witness))
|
||||
|
||||
init_types = ["init"]
|
||||
if allregs:
|
||||
init_types.append("reg")
|
||||
|
||||
seq_types = ["seq"]
|
||||
if blackbox:
|
||||
seq_types.append("blackbox")
|
||||
|
||||
def worker(mod, path, cursor):
|
||||
cell_paths = {}
|
||||
for witness in self.modinfo[mod].witness:
|
||||
if witness["type"] in init_types:
|
||||
init_witnesses.append(absolute(path, cursor, witness))
|
||||
if witness["type"] in seq_types:
|
||||
seq_witnesses.append(absolute(path, cursor, witness))
|
||||
if witness["type"] == "mem":
|
||||
if allregs and not witness["rom"]:
|
||||
width, size = witness["width"], witness["size"]
|
||||
witness = {**witness, "uninitialized": {"width": width * size, "offset": 0}}
|
||||
if not witness["uninitialized"]:
|
||||
continue
|
||||
|
||||
mem_witnesses.append(absolute(path, cursor, witness))
|
||||
if witness["type"] == "cell":
|
||||
cell_paths[witness["smtname"]] = tuple(witness["path"])
|
||||
|
||||
for cellname, celltype in sorted(self.modinfo[mod].cells.items()):
|
||||
worker(celltype, path + cell_paths.get(cellname, ("?" + cellname,)), cursor + [cellname])
|
||||
|
||||
worker(top, (), [])
|
||||
return init_witnesses, seq_witnesses, clk_witnesses, mem_witnesses
|
||||
|
||||
def read(self):
|
||||
stmt = []
|
||||
count_brackets = 0
|
||||
|
@ -887,6 +944,8 @@ class SmtIo:
|
|||
assert mod in self.modinfo
|
||||
if path[0] == "":
|
||||
return base
|
||||
if isinstance(path[0], int):
|
||||
return "(|%s#%d| %s)" % (mod, path[0], base)
|
||||
if path[0] in self.modinfo[mod].cells:
|
||||
return "(|%s_h %s| %s)" % (mod, path[0], base)
|
||||
if path[0] in self.modinfo[mod].wsize:
|
||||
|
@ -909,6 +968,8 @@ class SmtIo:
|
|||
mod = self.modinfo[mod].cells[net_path[i]]
|
||||
|
||||
assert mod in self.modinfo
|
||||
if isinstance(net_path[-1], int):
|
||||
return None
|
||||
assert net_path[-1] in self.modinfo[mod].wsize
|
||||
return self.modinfo[mod].wsize[net_path[-1]]
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue