Added symbiyosys to toolchains
Signed-off-by: Joppe Blondel <joppe@blondel.nl>
This commit is contained in:
@ -24,12 +24,23 @@ begin
|
|||||||
|
|
||||||
cnt <= std_logic_vector(icnt);
|
cnt <= std_logic_vector(icnt);
|
||||||
|
|
||||||
process(ACLK, ARESETN)
|
f_counter : if formal generate
|
||||||
|
begin
|
||||||
|
-- Set clock source for all assertions
|
||||||
|
default clock is rising_edge(ACLK);
|
||||||
|
-- Counter is always under mxcnt if it started under max
|
||||||
|
a_never_exceeds_max : assert (always (icnt<mxcnt) -> always (icnt<mxcnt));
|
||||||
|
-- Counter is always reset to 0
|
||||||
|
a_counter_reset_to_zero : assert (always (ARESETN='0') -> (icnt=0));
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
p_counter : process(ACLK, ARESETN)
|
||||||
begin
|
begin
|
||||||
if ARESETN='0' then
|
if ARESETN='0' then
|
||||||
icnt <= (others=>'0');
|
icnt <= (others=>'0');
|
||||||
elsif rising_edge(ACLK) then
|
elsif rising_edge(ACLK) then
|
||||||
if icnt<mxcnt then
|
-- Without this -1 the assertion wont hold
|
||||||
|
if icnt<mxcnt-1 then
|
||||||
icnt <= icnt + 1;
|
icnt <= icnt + 1;
|
||||||
else
|
else
|
||||||
icnt <= (others=>'0');
|
icnt <= (others=>'0');
|
||||||
|
22
examples/formal/SIM/counter.sby
Normal file
22
examples/formal/SIM/counter.sby
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[tasks]
|
||||||
|
bmc d_12
|
||||||
|
cover d_120
|
||||||
|
prove d_4
|
||||||
|
|
||||||
|
[options]
|
||||||
|
bmc:mode bmc
|
||||||
|
cover:mode cover
|
||||||
|
prove:mode prove
|
||||||
|
d_120:depth 120
|
||||||
|
d_12:depth 12
|
||||||
|
d_4:depth 4
|
||||||
|
|
||||||
|
[engines]
|
||||||
|
smtbmc
|
||||||
|
|
||||||
|
[script]
|
||||||
|
ghdl -fpsl --std=08 -gformal=true counter.vhd -e counter
|
||||||
|
prep -top counter
|
||||||
|
|
||||||
|
[files]
|
||||||
|
RTL/counter.vhd
|
@ -26,3 +26,16 @@ runtime = all
|
|||||||
files_vhdl = RTL/counter.vhd
|
files_vhdl = RTL/counter.vhd
|
||||||
SIM/tb_counter.vhd
|
SIM/tb_counter.vhd
|
||||||
# ######################################
|
# ######################################
|
||||||
|
|
||||||
|
# ######################################
|
||||||
|
# Formal verification with symbiyosys
|
||||||
|
[target.formal]
|
||||||
|
toolchain = symbiyosys
|
||||||
|
|
||||||
|
# Toolchain settings
|
||||||
|
sby_opts =
|
||||||
|
|
||||||
|
# Fileset
|
||||||
|
files_sby = SIM/counter.sby
|
||||||
|
files_other = RTL/counter.vhd
|
||||||
|
# ######################################
|
66
remotesyn/toolchains/symbiyosys.py
Normal file
66
remotesyn/toolchains/symbiyosys.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def execp(cmd, subprocesses, cwd):
|
||||||
|
p = subprocess.Popen(cmd,
|
||||||
|
shell=True, cwd=cwd,
|
||||||
|
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
subprocesses.append(p)
|
||||||
|
while p.poll() is None:
|
||||||
|
time.sleep(1)
|
||||||
|
res = p.returncode
|
||||||
|
return res
|
||||||
|
|
||||||
|
def do(config, target, log, subprocesses, prefix='.'):
|
||||||
|
shutil.rmtree(config.get('project', 'build_dir', fallback='build'), True)
|
||||||
|
|
||||||
|
log("Starting formal verification")
|
||||||
|
|
||||||
|
log(" - parsing options")
|
||||||
|
toplevel = config.get(f'target.{target}', 'toplevel', fallback='toplevel')
|
||||||
|
runtime = config.get(f'target.{target}', 'runtime', fallback='100 ns')
|
||||||
|
sby_opts = config.get(f'target.{target}', 'sby_opts', fallback='')
|
||||||
|
files_sby = config.get(f'target.{target}', 'files_sby', fallback='').split()
|
||||||
|
files_other = config.get(f'target.{target}', 'files_other', fallback='').split()
|
||||||
|
build_dir = config.get(f'project', 'build_dir', fallback='build')
|
||||||
|
out_dir = config.get(f'project', 'out_dir', fallback='out')
|
||||||
|
|
||||||
|
prefix = f'{os.getcwd()}/{prefix}'
|
||||||
|
build_dir = f'{prefix}/{build_dir}'
|
||||||
|
out_dir = f'{prefix}/{out_dir}/{target}'
|
||||||
|
|
||||||
|
log(" - creating output directories")
|
||||||
|
os.makedirs(build_dir, exist_ok=True)
|
||||||
|
os.makedirs(out_dir, exist_ok=True)
|
||||||
|
|
||||||
|
log(" - copy needed files")
|
||||||
|
for f in files_other:
|
||||||
|
d = os.path.dirname(f)
|
||||||
|
os.makedirs(f"{build_dir}/{d}", exist_ok=True)
|
||||||
|
shutil.copy(f"{prefix}/{f}", f"{build_dir}/{f}")
|
||||||
|
|
||||||
|
res = 0
|
||||||
|
for f in files_sby:
|
||||||
|
log(" - running sby for", f)
|
||||||
|
d = os.path.dirname(f)
|
||||||
|
os.makedirs(f"{build_dir}/{d}", exist_ok=True)
|
||||||
|
shutil.copy(f"{prefix}/{f}", f"{build_dir}/{f}")
|
||||||
|
|
||||||
|
res = execp(f"sby --prefix sby_{os.path.basename(f)} --yosys \"yosys -m ghdl\" {sby_opts} -f {f}", subprocesses, build_dir)
|
||||||
|
|
||||||
|
log(" - copy logs and output files")
|
||||||
|
oname = f'sby_{os.path.basename(f)}'
|
||||||
|
for d in os.listdir(f'{build_dir}'):
|
||||||
|
if os.path.isdir(f'{build_dir}/{d}') and d.startswith(oname):
|
||||||
|
shutil.copy(f'{build_dir}/{d}/logfile.txt', f'{out_dir}/{d}.log')
|
||||||
|
shutil.copytree(f'{build_dir}/{d}/engine_0', f'{out_dir}/{d}', dirs_exist_ok=True)
|
||||||
|
|
||||||
|
if res!=0:
|
||||||
|
log(" - [-]")
|
||||||
|
else:
|
||||||
|
log(" - [+]")
|
||||||
|
|
||||||
|
|
||||||
|
return 0
|
Reference in New Issue
Block a user