3
0
Fork 0
mirror of https://github.com/YosysHQ/sby.git synced 2025-04-23 05:15:30 +00:00
This commit is contained in:
KrystalDelusion 2025-03-26 14:03:38 +00:00 committed by GitHub
commit 687cffb806
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 368 additions and 4 deletions

View file

@ -0,0 +1,136 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import asyncio
import json
import re
from pathlib import Path
def arg_parser():
parser = argparse.ArgumentParser()
parser.add_argument(
"btor_file",
type=Path
)
parser.add_argument(
"ywb_file",
type=Path
)
parser.add_argument(
"-d", "--dest",
dest="dest",
required=False,
type=Path
)
return parser
def fix_path(path: str) -> list[str]:
if path[0] == '$':
fixed = [path]
else:
fixed = [f"\\{s}" for s in path.replace('[','.[').split('.')]
return fixed
async def main() -> None:
args = arg_parser().parse_args()
work_dir: Path = args.dest or Path()
proc = await asyncio.create_subprocess_shell(
f"btor2aiger {args.btor_file}",
stdout=asyncio.subprocess.PIPE
)
data = True
# output aig
aig_file = work_dir / "design_aiger.aig"
aigf = open(aig_file, mode="wb")
data = await proc.stdout.readline()
aig_header = data.decode()
while data:
aigf.write(data)
data = await proc.stdout.readline()
if b'i0' in data:
break
end_pos = data.find(b'i0')
aigf.write(data[:end_pos])
aigf.close()
# initialize yw aiger map
aig_MILOA = aig_header.split()
ywa = {
"version": "Yosys Witness Aiger map",
"generator": "btor2aig_yw.py",
"latch_count": int(aig_MILOA[3]),
"input_count": int(aig_MILOA[2]),
"clocks": [],
"inputs": [],
"seqs": [],
"inits": [],
"latches": [],
"asserts": [],
"assumes": []
}
# output aim & build ywa
aim_file = work_dir / "design_aiger.aim"
aimf = open(aim_file, mode="w")
data = data[end_pos:]
while data:
# decode data
string = data.decode().rstrip()
pattern = r"(?P<type>[cil])(?P<input>\d+) (?P<path>.*?)(\[(?P<offset>\d+)\])?$"
m = re.match(pattern, string)
md = m.groupdict()
md['input'] = int(md['input'])
if md['type'] == 'i':
md['type'] = 'input'
elif md['type'] == 'c':
md['type'] = 'clk'
elif md['type'] == 'l':
md['type'] = 'latch'
md['input'] += ywa['input_count']
else:
raise ValueError(f"Unknown type identifier {md['type']!r}")
for k in ['input', 'offset']:
if md[k]:
md[k] = int(md[k])
else:
md[k] = 0
# output to aim
if md['type'] in ['input', 'latch']:
print("{type} {input} {offset} {path}".format(**md), file=aimf)
# update ywa
md_type = md.pop('type')
md['path'] = fix_path(md['path'])
if md_type == 'clk':
md['edge'] = "posedge" # always?
ywa['clocks'].append(md)
elif md_type == 'input':
ywa['inputs'].append(md)
elif md_type == 'latch':
ywa['inits'].append(md)
# get next line
data = await proc.stdout.readline()
aimf.close()
with open(args.ywb_file, mode='r') as f:
data = json.load(f)
ywa['asserts'].extend(data['asserts'])
ywa['assumes'].extend(data['assumes'])
with open(work_dir / "design_aiger.ywa", mode="w") as f:
json.dump(ywa, f, indent=2)
if __name__ == "__main__":
asyncio.run(main())