mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-07 06:33:24 +00:00
More yosys-smtbmc smtc features
This commit is contained in:
parent
ee3e7a0e45
commit
ad56ad44c3
5 changed files with 97 additions and 20 deletions
|
@ -20,6 +20,7 @@
|
||||||
import os, sys, getopt, re
|
import os, sys, getopt, re
|
||||||
##yosys-sys-path##
|
##yosys-sys-path##
|
||||||
from smtio import smtio, smtopts, mkvcd
|
from smtio import smtio, smtopts, mkvcd
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
skip_steps = 0
|
skip_steps = 0
|
||||||
step_size = 1
|
step_size = 1
|
||||||
|
@ -120,43 +121,70 @@ if tempind and len(inconstr) != 0:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
constr_asserts = dict()
|
constr_asserts = defaultdict(list)
|
||||||
constr_assumes = dict()
|
constr_assumes = defaultdict(list)
|
||||||
|
|
||||||
for fn in inconstr:
|
for fn in inconstr:
|
||||||
current_state = None
|
current_states = None
|
||||||
|
|
||||||
with open(fn, "r") as f:
|
with open(fn, "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
|
if line.startswith("#"):
|
||||||
|
continue
|
||||||
|
|
||||||
tokens = line.split()
|
tokens = line.split()
|
||||||
|
|
||||||
if len(tokens) == 0:
|
if len(tokens) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if tokens[0] == "initial":
|
if tokens[0] == "initial":
|
||||||
current_state = 0
|
current_states = set()
|
||||||
|
current_states.add(0)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if tokens[0] == "state":
|
if tokens[0] == "state":
|
||||||
current_state = int(tokens[1])
|
current_states = set()
|
||||||
|
for token in tokens[1:]:
|
||||||
|
tok = token.split(":")
|
||||||
|
if len(tok) == 1:
|
||||||
|
current_states.add(int(token))
|
||||||
|
elif len(tok) == 2:
|
||||||
|
lower = int(tok[0])
|
||||||
|
if tok[1] == "*":
|
||||||
|
upper = num_steps
|
||||||
|
else:
|
||||||
|
upper = int(tok[1])
|
||||||
|
for i in range(lower, upper+1):
|
||||||
|
current_states.add(i)
|
||||||
|
else:
|
||||||
|
assert 0
|
||||||
|
continue
|
||||||
|
|
||||||
|
if tokens[0] == "always":
|
||||||
|
if len(tokens) == 1:
|
||||||
|
current_states = set(range(0, num_steps+1))
|
||||||
|
elif len(tokens) == 2:
|
||||||
|
i = int(tokens[1])
|
||||||
|
assert i < 0
|
||||||
|
current_states = set(range(-i, num_steps+1))
|
||||||
|
else:
|
||||||
|
assert 0
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if tokens[0] == "assert":
|
if tokens[0] == "assert":
|
||||||
assert current_state is not None
|
assert current_states is not None
|
||||||
|
|
||||||
if current_state not in constr_asserts:
|
for state in current_states:
|
||||||
constr_asserts[current_state] = list()
|
constr_asserts[state].append(" ".join(tokens[1:]))
|
||||||
|
|
||||||
constr_asserts[current_state].append(" ".join(tokens[1:]))
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if tokens[0] == "assume":
|
if tokens[0] == "assume":
|
||||||
assert current_state is not None
|
assert current_states is not None
|
||||||
|
|
||||||
if current_state not in constr_assumes:
|
for state in current_states:
|
||||||
constr_assumes[current_state] = list()
|
constr_assumes[state].append(" ".join(tokens[1:]))
|
||||||
|
|
||||||
constr_assumes[current_state].append(" ".join(tokens[1:]))
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
assert 0
|
assert 0
|
||||||
|
@ -166,9 +194,25 @@ def get_constr_expr(db, state):
|
||||||
if state not in db:
|
if state not in db:
|
||||||
return "true"
|
return "true"
|
||||||
|
|
||||||
|
netref_regex = re.compile(r'(^|[( ])\[(-?[0-9]+:|)([^\]]+)\](?=[ )]|$)')
|
||||||
|
|
||||||
|
def replace_netref(match):
|
||||||
|
state_sel = match.group(2)
|
||||||
|
|
||||||
|
if state_sel == "":
|
||||||
|
st = state
|
||||||
|
elif state_sel[0] == "-":
|
||||||
|
st = state + int(state_sel[:-1])
|
||||||
|
else:
|
||||||
|
st = int(state_sel[:-1])
|
||||||
|
|
||||||
|
expr = smt.net_expr(topmod, "s%d" % st, smt.get_path(topmod, match.group(3)))
|
||||||
|
|
||||||
|
return match.group(1) + expr
|
||||||
|
|
||||||
expr_list = list()
|
expr_list = list()
|
||||||
for expr in db[state]:
|
for expr in db[state]:
|
||||||
expr = re.sub(r'\[([^\]]+)\]', lambda match: smt.net_expr(topmod, "s%d" % state, smt.get_path(topmod, match.group(1))), expr)
|
expr = netref_regex.sub(replace_netref, expr)
|
||||||
expr_list.append(expr)
|
expr_list.append(expr)
|
||||||
|
|
||||||
if len(expr_list) == 0:
|
if len(expr_list) == 0:
|
||||||
|
@ -430,7 +474,7 @@ if tempind:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
else: # not tempind, not gentrace
|
else: # not tempind
|
||||||
step = 0
|
step = 0
|
||||||
retstatus = True
|
retstatus = True
|
||||||
while step < num_steps:
|
while step < num_steps:
|
||||||
|
|
5
examples/smtbmc/.gitignore
vendored
5
examples/smtbmc/.gitignore
vendored
|
@ -1,9 +1,12 @@
|
||||||
demo1.smt2
|
demo1.smt2
|
||||||
demo1.yslog
|
demo1.yslog
|
||||||
demo2.smt2
|
demo2.smt2
|
||||||
|
demo2.smtc
|
||||||
demo2.vcd
|
demo2.vcd
|
||||||
demo2.yslog
|
demo2.yslog
|
||||||
demo2_tb
|
demo2_tb
|
||||||
demo2_tb.smtc
|
|
||||||
demo2_tb.v
|
demo2_tb.v
|
||||||
demo2_tb.vcd
|
demo2_tb.vcd
|
||||||
|
demo3.smt2
|
||||||
|
demo3.vcd
|
||||||
|
demo3.yslog
|
||||||
|
|
|
@ -1,24 +1,31 @@
|
||||||
|
|
||||||
all: demo1 demo2
|
all: demo1 demo2 demo3
|
||||||
|
|
||||||
demo1: demo1.smt2
|
demo1: demo1.smt2
|
||||||
yosys-smtbmc --dump-vcd demo1.vcd demo1.smt2
|
yosys-smtbmc --dump-vcd demo1.vcd demo1.smt2
|
||||||
yosys-smtbmc -i --dump-vcd demo1.vcd demo1.smt2
|
yosys-smtbmc -i --dump-vcd demo1.vcd demo1.smt2
|
||||||
|
|
||||||
demo2: demo2.smt2
|
demo2: demo2.smt2
|
||||||
yosys-smtbmc -g --dump-vcd demo2.vcd --dump-vlogtb demo2_tb.v --dump-smtc demo2_tb.smtc demo2.smt2
|
yosys-smtbmc -g --dump-vcd demo2.vcd --dump-smtc demo2.smtc --dump-vlogtb demo2_tb.v demo2.smt2
|
||||||
iverilog -g2012 -o demo2_tb demo2_tb.v demo2.v
|
iverilog -g2012 -o demo2_tb demo2_tb.v demo2.v
|
||||||
vvp demo2_tb +vcd=demo2_tb.vcd
|
vvp demo2_tb +vcd=demo2_tb.vcd
|
||||||
|
|
||||||
|
demo3: demo3.smt2
|
||||||
|
yosys-smtbmc --dump-vcd demo3.vcd --smtc demo3.smtc demo3.smt2
|
||||||
|
|
||||||
demo1.smt2: demo1.v
|
demo1.smt2: demo1.v
|
||||||
yosys -ql demo1.yslog -p 'read_verilog -formal demo1.v; prep -top demo1 -nordff; write_smt2 -wires -mem -bv demo1.smt2'
|
yosys -ql demo1.yslog -p 'read_verilog -formal demo1.v; prep -top demo1 -nordff; write_smt2 -wires -mem -bv demo1.smt2'
|
||||||
|
|
||||||
demo2.smt2: demo2.v
|
demo2.smt2: demo2.v
|
||||||
yosys -ql demo2.yslog -p 'read_verilog -formal demo2.v; prep -top demo2 -nordff; write_smt2 -wires -mem -bv demo2.smt2'
|
yosys -ql demo2.yslog -p 'read_verilog -formal demo2.v; prep -top demo2 -nordff; write_smt2 -wires -mem -bv demo2.smt2'
|
||||||
|
|
||||||
|
demo3.smt2: demo3.v
|
||||||
|
yosys -ql demo3.yslog -p 'read_verilog -formal demo3.v; prep -top demo3 -nordff; write_smt2 -wires -mem -bv demo3.smt2'
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f demo1.yslog demo1.smt2 demo1.vcd
|
rm -f demo1.yslog demo1.smt2 demo1.vcd
|
||||||
rm -f demo2.yslog demo2.smt2 demo2.vcd demo2_tb.v demo2_tb demo2_tb.vcd demo2_tb.smtc
|
rm -f demo2.yslog demo2.smt2 demo2.vcd demo2.smtc demo2_tb.v demo2_tb demo2_tb.vcd
|
||||||
|
rm -f demo3.yslog demo3.smt2 demo3.vcd
|
||||||
|
|
||||||
.PHONY: demo1 clean
|
.PHONY: demo1 demo2 demo3 clean
|
||||||
|
|
||||||
|
|
5
examples/smtbmc/demo3.smtc
Normal file
5
examples/smtbmc/demo3.smtc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
initial
|
||||||
|
assume [rst]
|
||||||
|
|
||||||
|
always -1
|
||||||
|
assert (= [-1:mem] [mem])
|
18
examples/smtbmc/demo3.v
Normal file
18
examples/smtbmc/demo3.v
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Whatever the initial content of this memory is at reset, it will never change
|
||||||
|
// see demo3.smtc for assumptions and assertions
|
||||||
|
|
||||||
|
module demo3(input clk, rst, input [15:0] addr, output reg [31:0] data);
|
||||||
|
reg [31:0] mem [0:2**16-1];
|
||||||
|
reg [15:0] addr_q;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
data <= mem[0] ^ 123456789;
|
||||||
|
addr_q <= 0;
|
||||||
|
end else begin
|
||||||
|
mem[addr_q] <= data ^ 123456789;
|
||||||
|
data <= mem[addr] ^ 123456789;
|
||||||
|
addr_q <= addr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
Loading…
Add table
Add a link
Reference in a new issue