Progress with smt2-based bmc scripts
This commit is contained in:
parent
12e64c7968
commit
8397962424
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import os, sys, getopt
|
import os, sys, getopt
|
||||||
|
from time import time
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
steps = 20
|
steps = 20
|
||||||
|
@ -118,6 +119,7 @@ def yices_get_net_bin(mod_name, net_name, state_name):
|
||||||
# Main Program
|
# Main Program
|
||||||
#####################################
|
#####################################
|
||||||
|
|
||||||
|
start_time = time()
|
||||||
yices_write("(set-logic QF_AUFBV)")
|
yices_write("(set-logic QF_AUFBV)")
|
||||||
|
|
||||||
with open("mem_equiv_a.smt2", "r") as f:
|
with open("mem_equiv_a.smt2", "r") as f:
|
||||||
|
@ -126,35 +128,48 @@ with open("mem_equiv_a.smt2", "r") as f:
|
||||||
with open("mem_equiv_b.smt2", "r") as f:
|
with open("mem_equiv_b.smt2", "r") as f:
|
||||||
for line in f: yices_write(line)
|
for line in f: yices_write(line)
|
||||||
|
|
||||||
# set-up states and transaction, reset for two cycles
|
for step in range(steps):
|
||||||
for i in range(steps):
|
yices_write("(declare-fun a%d () main_a_s)" % step)
|
||||||
yices_write("(declare-fun a%d () main_a_s)" % i)
|
yices_write("(declare-fun b%d () main_b_s)" % step)
|
||||||
yices_write("(declare-fun b%d () main_b_s)" % i)
|
|
||||||
if i > 0:
|
|
||||||
yices_write("(assert (main_a_t a%d a%d))" % (i-1, i))
|
|
||||||
yices_write("(assert (main_b_t b%d b%d))" % (i-1, i))
|
|
||||||
if i > 1:
|
|
||||||
yices_write("(assert (|main_a_n resetn| a%d))" % i)
|
|
||||||
yices_write("(assert (|main_b_n resetn| b%d))" % i)
|
|
||||||
else:
|
|
||||||
yices_write("(assert (not (|main_a_n resetn| a%d)))" % i)
|
|
||||||
yices_write("(assert (not (|main_b_n resetn| b%d)))" % i)
|
|
||||||
|
|
||||||
|
# reset in first two cycles
|
||||||
|
if step < 2:
|
||||||
|
yices_write("(assert (not (|main_a_n resetn| a%d)))" % step)
|
||||||
|
yices_write("(assert (not (|main_b_n resetn| b%d)))" % step)
|
||||||
|
|
||||||
|
else:
|
||||||
|
yices_write("(assert (|main_a_n resetn| a%d))" % step)
|
||||||
|
yices_write("(assert (|main_b_n resetn| b%d))" % step)
|
||||||
|
|
||||||
|
if step == 0:
|
||||||
# start with synced memory and register file
|
# start with synced memory and register file
|
||||||
yices_write("(assert (= (|main_a_m cpu.cpuregs| a0) (|main_b_m cpu.cpuregs| b0)))")
|
yices_write("(assert (= (|main_a_m cpu.cpuregs| a0) (|main_b_m cpu.cpuregs| b0)))")
|
||||||
yices_write("(assert (= (|main_a_m memory| a0) (|main_b_m memory| b0)))")
|
yices_write("(assert (= (|main_a_m memory| a0) (|main_b_m memory| b0)))")
|
||||||
|
|
||||||
|
else:
|
||||||
|
yices_write("(assert (main_a_t a%d a%d))" % (step-1, step))
|
||||||
|
yices_write("(assert (main_b_t b%d b%d))" % (step-1, step))
|
||||||
|
|
||||||
|
secs = int(time() - start_time)
|
||||||
|
print("[%3d:%02d:%02d] Checking sequence of length %d.." % (secs // (60*60), (secs // 60) % 60, secs % 60, step))
|
||||||
|
yices_write("(push 1)")
|
||||||
|
|
||||||
# stop with a trap and no pending memory xfer
|
# stop with a trap and no pending memory xfer
|
||||||
yices_write("(assert (not (|main_a_n mem_valid| a%d)))" % (steps-1))
|
yices_write("(assert (not (|main_a_n mem_valid| a%d)))" % step)
|
||||||
yices_write("(assert (not (|main_b_n mem_valid| b%d)))" % (steps-1))
|
yices_write("(assert (not (|main_b_n mem_valid| b%d)))" % step)
|
||||||
yices_write("(assert (|main_a_n trap| a%d))" % (steps-1))
|
yices_write("(assert (|main_a_n trap| a%d))" % step)
|
||||||
yices_write("(assert (|main_b_n trap| b%d))" % (steps-1))
|
yices_write("(assert (|main_b_n trap| b%d))" % step)
|
||||||
yices_write("(assert (|main_a_n trap| a%d))" % (steps-2))
|
|
||||||
yices_write("(assert (|main_b_n trap| b%d))" % (steps-2))
|
|
||||||
|
|
||||||
# look for differences in memory or register file
|
# look for differences in memory or register file
|
||||||
yices_write(("(assert (or (distinct (|main_a_m cpu.cpuregs| a%d) (|main_b_m cpu.cpuregs| b%d)) " +
|
yices_write(("(assert (or (distinct (|main_a_m cpu.cpuregs| a%d) (|main_b_m cpu.cpuregs| b%d)) " +
|
||||||
"(distinct (|main_a_m memory| a%d) (|main_b_m memory| b%d))))") % (steps-1, steps-1, steps-1, steps-1))
|
"(distinct (|main_a_m memory| a%d) (|main_b_m memory| b%d))))") % (step, step, step, step))
|
||||||
|
|
||||||
|
yices_write("(check-sat)")
|
||||||
|
|
||||||
|
if yices_read() == "sat":
|
||||||
|
|
||||||
|
secs = int(time() - start_time)
|
||||||
|
print("[%3d:%02d:%02d] Creating model.." % (secs // (60*60), (secs // 60) % 60, secs % 60))
|
||||||
|
|
||||||
def make_cpu_regs(step):
|
def make_cpu_regs(step):
|
||||||
for i in range(1, 32):
|
for i in range(1, 32):
|
||||||
|
@ -162,9 +177,8 @@ def make_cpu_regs(step):
|
||||||
yices_write("(define-fun b%d_r%d () (_ BitVec 32) (select (|main_b_m cpu.cpuregs| b%d) #b%s))" % (step, i, step, bin(32+i)[3:]))
|
yices_write("(define-fun b%d_r%d () (_ BitVec 32) (select (|main_b_m cpu.cpuregs| b%d) #b%s))" % (step, i, step, bin(32+i)[3:]))
|
||||||
|
|
||||||
make_cpu_regs(0)
|
make_cpu_regs(0)
|
||||||
make_cpu_regs(steps-1)
|
make_cpu_regs(step)
|
||||||
|
|
||||||
print("checking...")
|
|
||||||
yices_write("(check-sat)")
|
yices_write("(check-sat)")
|
||||||
|
|
||||||
def print_status(mod, step):
|
def print_status(mod, step):
|
||||||
|
@ -189,29 +203,28 @@ def print_cpu_regs(step):
|
||||||
rb = yices_bv2hex(yices_get("b%d_r%d" % (step, i)))
|
rb = yices_bv2hex(yices_get("b%d_r%d" % (step, i)))
|
||||||
print("%3s[%d]: A=%s B=%s%s" % ("x%d" % i, step, ra, rb, " !" if ra != rb else ""))
|
print("%3s[%d]: A=%s B=%s%s" % ("x%d" % i, step, ra, rb, " !" if ra != rb else ""))
|
||||||
|
|
||||||
if yices_read() == "sat":
|
assert yices_read() == "sat"
|
||||||
print("yices returned sat -> model check failed!")
|
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print_cpu_regs(0)
|
print_cpu_regs(0)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print_cpu_regs(steps-1)
|
print_cpu_regs(step)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
for i in range(steps):
|
for i in range(step+1):
|
||||||
print_status("a", i)
|
print_status("a", i)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
for i in range(steps):
|
for i in range(step+1):
|
||||||
print_status("b", i)
|
print_status("b", i)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
for i in range(1, steps):
|
for i in range(1, step+1):
|
||||||
print_mem_xfer("a", i)
|
print_mem_xfer("a", i)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
for i in range(1, steps):
|
for i in range(1, step+1):
|
||||||
print_mem_xfer("b", i)
|
print_mem_xfer("b", i)
|
||||||
|
|
||||||
with open("mem_equiv_tb.v", "w") as f:
|
with open("mem_equiv_tb.v", "w") as f:
|
||||||
|
@ -220,7 +233,7 @@ if yices_read() == "sat":
|
||||||
|
|
||||||
memory_words = 1
|
memory_words = 1
|
||||||
memory_datas = { "a": dict(), "b": dict() }
|
memory_datas = { "a": dict(), "b": dict() }
|
||||||
for i in range(steps-1, 0, -1):
|
for i in range(step, 0, -1):
|
||||||
for mod in ["a", "b"]:
|
for mod in ["a", "b"]:
|
||||||
if yices_get("(and (|main_%s_n mem_valid| %s%d) (|main_%s_n mem_ready| %s%d))" % (mod, mod, i, mod, mod, i)) == 'true':
|
if yices_get("(and (|main_%s_n mem_valid| %s%d) (|main_%s_n mem_ready| %s%d))" % (mod, mod, i, mod, mod, i)) == 'true':
|
||||||
mem_addr = yices_get_net_hex("main_" + mod, "mem_addr", "%s%d" % (mod, i))
|
mem_addr = yices_get_net_hex("main_" + mod, "mem_addr", "%s%d" % (mod, i))
|
||||||
|
@ -293,7 +306,7 @@ if yices_read() == "sat":
|
||||||
print(" main_b.memory['h %s] = 'h %s;" % (addr, data), file=f)
|
print(" main_b.memory['h %s] = 'h %s;" % (addr, data), file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
for i in range(steps):
|
for i in range(step+1):
|
||||||
print(" resetn = %d;" % yices_get_net_bool("main_a", "resetn", "a%d" % i), file=f)
|
print(" resetn = %d;" % yices_get_net_bool("main_a", "resetn", "a%d" % i), file=f)
|
||||||
print(" domem_a = %d;" % yices_get_net_bool("main_a", "domem", "a%d" % i), file=f)
|
print(" domem_a = %d;" % yices_get_net_bool("main_a", "domem", "a%d" % i), file=f)
|
||||||
print(" domem_b = %d;" % yices_get_net_bool("main_b", "domem", "b%d" % i), file=f)
|
print(" domem_b = %d;" % yices_get_net_bool("main_b", "domem", "b%d" % i), file=f)
|
||||||
|
@ -310,11 +323,12 @@ if yices_read() == "sat":
|
||||||
print(" end", file=f)
|
print(" end", file=f)
|
||||||
print("endmodule", file=f)
|
print("endmodule", file=f)
|
||||||
|
|
||||||
print("running verilog test bench...")
|
secs = int(time() - start_time)
|
||||||
os.system("iverilog -o mem_equiv_tb -s testbench mem_equiv_tb.v mem_equiv.v ../../picorv32.v && ./mem_equiv_tb")
|
print("[%3d:%02d:%02d] Done." % (secs // (60*60), (secs // 60) % 60, secs % 60))
|
||||||
|
break
|
||||||
|
|
||||||
else:
|
else: # unsat
|
||||||
print("yices returned unsat -> model check passed.")
|
yices_write("(pop 1)")
|
||||||
|
|
||||||
yices_write("(exit)")
|
yices_write("(exit)")
|
||||||
yices.wait()
|
yices.wait()
|
||||||
|
|
|
@ -15,6 +15,7 @@ module main (input clk, resetn, domem, output trap);
|
||||||
(* keep *) wire [31:0] mem_rdata;
|
(* keep *) wire [31:0] mem_rdata;
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
|
.ENABLE_COUNTERS ( 0),
|
||||||
.ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
|
.ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
|
||||||
.TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ),
|
.TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ),
|
||||||
.TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ),
|
.TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ),
|
||||||
|
|
Loading…
Reference in New Issue