mirror of https://github.com/YosysHQ/yosys.git
Added "yosys-smtbmc --dump-vlogtb"
This commit is contained in:
parent
ed785194de
commit
f7578b0239
|
@ -60,6 +60,9 @@ yosys-smtbmc [options] <yosys_smt2_output>
|
|||
write trace to this VCD file
|
||||
(hint: use 'write_smt2 -wires' for maximum
|
||||
coverage of signals in generated VCD file)
|
||||
|
||||
--dump-vlogtb <verilog_filename>
|
||||
write trace as Verilog test bench
|
||||
""" + so.helpmsg())
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -83,6 +86,8 @@ for o, a in opts:
|
|||
step_size = int(a)
|
||||
elif o == "--dump-vcd":
|
||||
vcdfile = a
|
||||
elif o == "--dump-vlogtb":
|
||||
vlogtbfile = a
|
||||
elif o == "-i":
|
||||
tempind = True
|
||||
elif o == "-g":
|
||||
|
@ -116,16 +121,22 @@ assert topmod in smt.modinfo
|
|||
|
||||
|
||||
def write_vcd_trace(steps):
|
||||
print("%s Writing model to VCD file." % smt.timestamp())
|
||||
print("%s Writing trace to VCD file." % smt.timestamp())
|
||||
|
||||
vcd = mkvcd(open(vcdfile, "w"))
|
||||
path_list = list()
|
||||
|
||||
for netpath in sorted(smt.hiernets(topmod)):
|
||||
vcd.add_net([topmod] + netpath, smt.net_width(topmod, netpath))
|
||||
hidden_net = False
|
||||
for n in netpath:
|
||||
if n.startswith("$"):
|
||||
hidden_net = True
|
||||
if not hidden_net:
|
||||
vcd.add_net([topmod] + netpath, smt.net_width(topmod, netpath))
|
||||
path_list.append(netpath)
|
||||
|
||||
for i in range(steps):
|
||||
vcd.set_time(i)
|
||||
path_list = sorted(smt.hiernets(topmod))
|
||||
value_list = smt.get_net_bin_list(topmod, path_list, "s%d" % i)
|
||||
for path, value in zip(path_list, value_list):
|
||||
vcd.set_net([topmod] + path, value)
|
||||
|
@ -133,6 +144,97 @@ def write_vcd_trace(steps):
|
|||
vcd.set_time(steps)
|
||||
|
||||
|
||||
def write_vlogtb_trace(steps):
|
||||
print("%s Writing trace to Verilog testbench." % smt.timestamp())
|
||||
|
||||
with open(vlogtbfile, "w") as f:
|
||||
print("module testbench;", file=f)
|
||||
print(" reg [4095:0] vcdfile;", file=f)
|
||||
print(" reg clock = 0, genclock = 1;", file=f)
|
||||
|
||||
primary_inputs = list()
|
||||
clock_inputs = set()
|
||||
|
||||
for name in smt.modinfo[topmod].inputs:
|
||||
if name in ["clk", "clock", "CLK", "CLOCK"]:
|
||||
clock_inputs.add(name)
|
||||
width = smt.modinfo[topmod].wsize[name]
|
||||
primary_inputs.append((name, width))
|
||||
|
||||
for name, width in primary_inputs:
|
||||
if name in clock_inputs:
|
||||
print(" wire [%d:0] PI_%s = clock;" % (width-1, name), file=f)
|
||||
else:
|
||||
print(" reg [%d:0] PI_%s;" % (width-1, name), file=f)
|
||||
|
||||
print(" %s UUT (" % topmod, file=f)
|
||||
for i in range(len(primary_inputs)):
|
||||
name, width = primary_inputs[i]
|
||||
last_pi = i+1 == len(primary_inputs)
|
||||
print(" .%s(PI_%s)%s" % (name, name, "" if last_pi else ","), file=f)
|
||||
print(" );", file=f)
|
||||
|
||||
print(" initial begin", file=f)
|
||||
print(" if ($value$plusargs(\"vcd=%s\", vcdfile)) begin", file=f)
|
||||
print(" $dumpfile(vcdfile);", file=f)
|
||||
print(" $dumpvars(0, testbench);", file=f)
|
||||
print(" end", file=f)
|
||||
print(" while (genclock) begin", file=f)
|
||||
print(" #5; clock = 0;", file=f)
|
||||
print(" #5; clock = 1;", file=f)
|
||||
print(" end", file=f)
|
||||
print(" end", file=f)
|
||||
|
||||
print(" initial begin", file=f)
|
||||
|
||||
regs = sorted(smt.hiernets(topmod, regs_only=True))
|
||||
regvals = smt.get_net_bin_list(topmod, regs, "s0")
|
||||
|
||||
print(" #1;", file=f);
|
||||
for reg, val in zip(regs, regvals):
|
||||
hidden_net = False
|
||||
for n in reg:
|
||||
if n.startswith("$"):
|
||||
hidden_net = True
|
||||
print(" %sUUT.%s = %d'b%s;" % ("// " if hidden_net else "", ".".join(reg), len(val), val), file=f)
|
||||
|
||||
mems = sorted(smt.hiermems(topmod))
|
||||
for mempath in mems:
|
||||
mem, abits, width = smt.mem_expr(topmod, "s0", mempath)
|
||||
|
||||
expr_list = list()
|
||||
for i in range(2**abits):
|
||||
expr_list.append("(select %s #b%s)" % (mem, format(i, "0%db" % abits)))
|
||||
|
||||
for i, val in enumerate(smt.get_list(expr_list)):
|
||||
val = smt.bv2bin(val)
|
||||
print(" UUT.%s[%d] = %d'b%s;" % (".".join(mempath), i, len(val), val), file=f)
|
||||
|
||||
for i in range(steps):
|
||||
pi_names = [[name] for name, _ in primary_inputs if name not in clock_inputs]
|
||||
pi_values = smt.get_net_bin_list(topmod, pi_names, "s%d" % i)
|
||||
|
||||
print(" #1;", file=f);
|
||||
print(" // state %d" % i, file=f);
|
||||
if i > 0:
|
||||
print(" @(posedge clock);", file=f);
|
||||
for name, val in zip(pi_names, pi_values):
|
||||
print(" PI_%s <= %d'b%s;" % (".".join(name), len(val), val), file=f)
|
||||
|
||||
print(" genclock = 0;", file=f);
|
||||
print(" end", file=f)
|
||||
|
||||
print("endmodule", file=f)
|
||||
|
||||
|
||||
def write_trace(steps):
|
||||
if vcdfile is not None:
|
||||
write_vcd_trace(steps)
|
||||
|
||||
if vlogtbfile is not None:
|
||||
write_vlogtb_trace(steps)
|
||||
|
||||
|
||||
def print_failed_asserts(mod, state, path):
|
||||
assert mod in smt.modinfo
|
||||
|
||||
|
@ -179,8 +281,7 @@ if tempind:
|
|||
if step == 0:
|
||||
print("%s Temporal induction failed!" % smt.timestamp())
|
||||
print_failed_asserts(topmod, "s%d" % step, topmod)
|
||||
if vcdfile is not None:
|
||||
write_vcd_trace(num_steps+1)
|
||||
write_trace(num_steps+1)
|
||||
|
||||
else:
|
||||
print("%s Temporal induction successful." % smt.timestamp())
|
||||
|
@ -206,8 +307,7 @@ elif gentrace:
|
|||
print("%s Creating trace of length %d.." % (smt.timestamp(), num_steps))
|
||||
|
||||
if smt.check_sat() == "sat":
|
||||
if vcdfile is not None:
|
||||
write_vcd_trace(num_steps)
|
||||
write_trace(num_steps)
|
||||
|
||||
else:
|
||||
print("%s Creating trace failed!" % smt.timestamp())
|
||||
|
@ -259,8 +359,7 @@ else: # not tempind, not gentrace
|
|||
if smt.check_sat() == "sat":
|
||||
print("%s BMC failed!" % smt.timestamp())
|
||||
print_failed_asserts(topmod, "s%d" % step, topmod)
|
||||
if vcdfile is not None:
|
||||
write_vcd_trace(step+step_size)
|
||||
write_trace(step+step_size)
|
||||
retstatus = False
|
||||
break
|
||||
|
||||
|
|
Loading…
Reference in New Issue