From fd1cc0c73d402f0db2c964537b38321f59c116b3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 26 Feb 2017 10:58:34 +0100 Subject: Improve (and fix for stbv mode) SMT2 memory API --- backends/smt2/smt2.cc | 49 ++++++++++++++++++++++++------------------------- backends/smt2/smtbmc.py | 43 ++++++++++++++++++++++++------------------- backends/smt2/smtio.py | 6 +++--- 3 files changed, 51 insertions(+), 47 deletions(-) (limited to 'backends/smt2') diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 6c2100f05..24731d1c7 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -560,7 +560,7 @@ struct Smt2Worker log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module)); - decls.push_back(stringf("(define-fun |%s_m:%d %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); std::string read_expr = "#b"; @@ -568,14 +568,14 @@ struct Smt2Worker read_expr += "0"; for (int k = 0; k < mem_size; k++) - read_expr = stringf("(ite (= (|%s_m:%d %s| state) #b%s) ((_ extract %d %d) (|%s#%d#0| state))\n %s)", + read_expr = stringf("(ite (= (|%s_m:R%dA %s| state) #b%s) ((_ extract %d %d) (|%s#%d#0| state))\n %s)", get_id(module), i, get_id(cell), Const(k+mem_offset, abits).as_string().c_str(), width*(k+1)-1, width*k, get_id(module), arrayid, read_expr.c_str()); decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d)\n %s) ; %s\n", get_id(module), idcounter, get_id(module), width, read_expr.c_str(), log_signal(data_sig))); - decls.push_back(stringf("(define-fun |%s_m:%dD %s| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| state))\n", + decls.push_back(stringf("(define-fun |%s_m:R%dD %s| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| state))\n", get_id(module), i, get_id(cell), get_id(module), width, get_id(module), idcounter)); register_bv(data_sig, idcounter++); @@ -599,13 +599,13 @@ struct Smt2Worker log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module)); - decls.push_back(stringf("(define-fun |%s_m:%d %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); - decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) (select (|%s#%d#0| state) (|%s_m:%d %s| state))) ; %s\n", + decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) (select (|%s#%d#0| state) (|%s_m:R%dA %s| state))) ; %s\n", get_id(module), idcounter, get_id(module), width, get_id(module), arrayid, get_id(module), i, get_id(cell), log_signal(data_sig))); - decls.push_back(stringf("(define-fun |%s_m:%dD %s| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| state))\n", + decls.push_back(stringf("(define-fun |%s_m:R%dD %s| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| state))\n", get_id(module), i, get_id(cell), get_id(module), width, get_id(module), idcounter)); register_bv(data_sig, idcounter++); @@ -792,7 +792,6 @@ struct Smt2Worker int abits = cell->getParam("\\ABITS").as_int(); int width = cell->getParam("\\WIDTH").as_int(); - int rd_ports = cell->getParam("\\RD_PORTS").as_int(); int wr_ports = cell->getParam("\\WR_PORTS").as_int(); if (statebv) @@ -810,17 +809,17 @@ struct Smt2Worker std::string data = get_bv(data_sig); std::string mask = get_bv(mask_sig); - decls.push_back(stringf("(define-fun |%s_m:%d %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), rd_ports+i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); - addr = stringf("(|%s_m:%d %s| state)", get_id(module), rd_ports+i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); + addr = stringf("(|%s_m:W%dA %s| state)", get_id(module), i, get_id(cell)); - decls.push_back(stringf("(define-fun |%s_m:%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), rd_ports+i, get_id(cell), get_id(module), width, data.c_str(), log_signal(data_sig))); - data = stringf("(|%s_m:%dD %s| state)", get_id(module), rd_ports+i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(cell), get_id(module), width, data.c_str(), log_signal(data_sig))); + data = stringf("(|%s_m:W%dD %s| state)", get_id(module), i, get_id(cell)); - decls.push_back(stringf("(define-fun |%s_m:%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), rd_ports+i, get_id(cell), get_id(module), width, mask.c_str(), log_signal(mask_sig))); - mask = stringf("(|%s_m:%dM %s| state)", get_id(module), rd_ports+i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(cell), get_id(module), width, mask.c_str(), log_signal(mask_sig))); + mask = stringf("(|%s_m:W%dM %s| state)", get_id(module), i, get_id(cell)); std::string data_expr; @@ -848,17 +847,17 @@ struct Smt2Worker std::string data = get_bv(data_sig); std::string mask = get_bv(mask_sig); - decls.push_back(stringf("(define-fun |%s_m:%d %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), rd_ports+i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); - addr = stringf("(|%s_m:%d %s| state)", get_id(module), rd_ports+i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); + addr = stringf("(|%s_m:W%dA %s| state)", get_id(module), i, get_id(cell)); - decls.push_back(stringf("(define-fun |%s_m:%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), rd_ports+i, get_id(cell), get_id(module), width, data.c_str(), log_signal(data_sig))); - data = stringf("(|%s_m:%dD %s| state)", get_id(module), rd_ports+i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(cell), get_id(module), width, data.c_str(), log_signal(data_sig))); + data = stringf("(|%s_m:W%dD %s| state)", get_id(module), i, get_id(cell)); - decls.push_back(stringf("(define-fun |%s_m:%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), rd_ports+i, get_id(cell), get_id(module), width, mask.c_str(), log_signal(mask_sig))); - mask = stringf("(|%s_m:%dM %s| state)", get_id(module), rd_ports+i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(cell), get_id(module), width, mask.c_str(), log_signal(mask_sig))); + mask = stringf("(|%s_m:W%dM %s| state)", get_id(module), i, get_id(cell)); data = stringf("(bvor (bvand %s %s) (bvand (select (|%s#%d#%d| state) %s) (bvnot %s)))", data.c_str(), mask.c_str(), get_id(module), arrayid, i, addr.c_str(), mask.c_str()); diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index 92a9a1a21..d1b45bb07 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -614,24 +614,26 @@ def write_vlogtb_trace(steps_start, steps_stop, index): mems = sorted(smt.hiermems(topmod)) for mempath in mems: abits, width, rports, wports = smt.mem_info(topmod, mempath) - mem = smt.mem_expr(topmod, "s%d" % steps_start, mempath) addr_expr_list = list() + data_expr_list = list() for i in range(steps_start, steps_stop): for j in range(rports): - addr_expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, j)) + addr_expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dA" % j)) + data_expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dD" % j)) - addr_list = set() - for val in smt.get_list(addr_expr_list): - addr_list.add(smt.bv2int(val)) + addr_list = smt.get_list(addr_expr_list) + data_list = smt.get_list(data_expr_list) - expr_list = list() - for i in addr_list: - expr_list.append("(select %s #b%s)" % (mem, format(i, "0%db" % abits))) + addr_data = dict() + for addr, data in zip(addr_list, data_list): + addr = smt.bv2bin(addr) + data = smt.bv2bin(data) + if addr not in addr_data: + addr_data[addr] = data - for i, val in zip(addr_list, 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 addr, data in addr_data.items(): + print(" UUT.%s[%d'b%s] = %d'b%s;" % (".".join(mempath), len(addr), addr, len(data), data), file=f) for i in range(steps_start, steps_stop): pi_names = [[name] for name, _ in primary_inputs if name not in clock_inputs] @@ -675,21 +677,24 @@ def write_constr_trace(steps_start, steps_stop, index): mems = sorted(smt.hiermems(topmod)) for mempath in mems: abits, width, rports, wports = smt.mem_info(topmod, mempath) - mem = smt.mem_expr(topmod, "s%d" % steps_start, mempath) addr_expr_list = list() + data_expr_list = list() for i in range(steps_start, steps_stop): for j in range(rports): - addr_expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, j)) + addr_expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dA" % j)) + data_expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dD" % j)) - addr_list = set((smt.bv2int(val) for val in smt.get_list(addr_expr_list))) + addr_list = smt.get_list(addr_expr_list) + data_list = smt.get_list(data_expr_list) - expr_list = list() - for i in addr_list: - expr_list.append("(select %s #b%s)" % (mem, format(i, "0%db" % abits))) + addr_data = dict() + for addr, data in zip(addr_list, data_list): + if addr not in addr_data: + addr_data[addr] = data - for i, val in zip(addr_list, smt.get_list(expr_list)): - print("assume (= (select [%s] #b%s) %s)" % (".".join(mempath), format(i, "0%db" % abits), val), file=f) + for addr, data in addr_data.items(): + print("assume (= (select [%s] %s) %s)" % (".".join(mempath), addr, data), file=f) for k in range(steps_start, steps_stop): print("", file=f) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 797539b9f..93133a462 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -596,20 +596,20 @@ class SmtIo: if mem_path[-1] not in self.modinfo[mod].memories: return False return True - def mem_expr(self, mod, base, path, portidx=None, infomode=False): + def mem_expr(self, mod, base, path, port=None, infomode=False): if len(path) == 1: assert mod in self.modinfo assert path[0] in self.modinfo[mod].memories if infomode: return self.modinfo[mod].memories[path[0]] - return "(|%s_m%s %s| %s)" % (mod, "" if portidx is None else ":%d" % portidx, path[0], base) + return "(|%s_m%s %s| %s)" % (mod, "" if port is None else ":%s" % port, path[0], base) assert mod in self.modinfo assert path[0] in self.modinfo[mod].cells nextmod = self.modinfo[mod].cells[path[0]] nextbase = "(|%s_h %s| %s)" % (mod, path[0], base) - return self.mem_expr(nextmod, nextbase, path[1:], portidx=portidx, infomode=infomode) + return self.mem_expr(nextmod, nextbase, path[1:], port=port, infomode=infomode) def mem_info(self, mod, path): return self.mem_expr(mod, "", path, infomode=True) -- cgit v1.2.3