diff options
Diffstat (limited to 'backends/smt2')
-rw-r--r-- | backends/smt2/Makefile.inc | 2 | ||||
-rw-r--r-- | backends/smt2/smt2.cc | 20 | ||||
-rw-r--r-- | backends/smt2/smtio.py | 50 |
3 files changed, 62 insertions, 10 deletions
diff --git a/backends/smt2/Makefile.inc b/backends/smt2/Makefile.inc index eacda2734..dce82f01a 100644 --- a/backends/smt2/Makefile.inc +++ b/backends/smt2/Makefile.inc @@ -6,7 +6,7 @@ ifneq ($(CONFIG),emcc) TARGETS += yosys-smtbmc yosys-smtbmc: backends/smt2/smtbmc.py - $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(__file__) + p for p in ["/share/python3", "/../share/yosys/python3"]]|;' < $< > $@.new + $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/yosys/python3"]]|;' < $< > $@.new $(Q) chmod +x $@.new $(Q) mv $@.new $@ diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 47c993d05..ca1ceacc7 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -135,6 +135,24 @@ struct Smt2Worker log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n", log_id(conn.first), log_id(module), log_id(cell), log_id(cell->type)); + if (cell->type.in("$mem") && conn.first.in("\\RD_CLK", "\\WR_CLK")) + { + SigSpec clk = sigmap(conn.second); + for (int i = 0; i < GetSize(clk); i++) + { + if (clk[i].wire == nullptr) + continue; + + if (cell->getParam(conn.first == "\\RD_CLK" ? "\\RD_CLK_ENABLE" : "\\WR_CLK_ENABLE")[i] != State::S1) + continue; + + if (cell->getParam(conn.first == "\\RD_CLK" ? "\\RD_CLK_POLARITY" : "\\WR_CLK_POLARITY")[i] == State::S1) + clock_posedge.insert(clk[i]); + else + clock_negedge.insert(clk[i]); + } + } + else if (cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_") && conn.first.in("\\CLK", "\\C")) { bool posedge = (cell->type == "$_DFF_N_") || (cell->type == "$dff" && cell->getParam("\\CLK_POLARITY").as_bool()); @@ -748,7 +766,7 @@ struct Smt2Worker if (statebv) makebits(stringf("%s_h %s", get_id(module), get_id(cell->name)), mod_stbv_width.at(cell->type)); - if (statedt) + else if (statedt) dtmembers.push_back(stringf(" (|%s_h %s| |%s_s|)\n", get_id(module), get_id(cell->name), get_id(cell->type))); else diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 1d5c89d8e..1a8d2484c 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -218,7 +218,7 @@ class SmtIo: def timestamp(self): secs = int(time() - self.start_time) - return "## %6d %3d:%02d:%02d " % (secs, secs // (60*60), (secs // 60) % 60, secs % 60) + return "## %3d:%02d:%02d " % (secs // (60*60), (secs // 60) % 60, secs % 60) def replace_in_stmt(self, stmt, pat, repl): if stmt == pat: @@ -294,20 +294,21 @@ class SmtIo: def p_read(self): assert self.p is not None - assert self.p_running if self.p_next is not None: data = self.p_next self.p_next = None return data + if not self.p_running: + return "" return self.p_queue.get() - def p_poll(self): + def p_poll(self, timeout=0.1): assert self.p is not None assert self.p_running if self.p_next is not None: return False try: - self.p_next = self.p_queue.get(True, 0.1) + self.p_next = self.p_queue.get(True, timeout) return False except Empty: return True @@ -580,12 +581,12 @@ class SmtIo: if count_brackets == 0: break if self.solver != "dummy" and self.p.poll(): - print("SMT Solver terminated unexpectedly: %s" % "".join(stmt), flush=True) + print("%s Solver terminated unexpectedly: %s" % (self.timestamp(), "".join(stmt)), flush=True) sys.exit(1) stmt = "".join(stmt) if stmt.startswith("(error"): - print("SMT Solver Error: %s" % stmt, file=sys.stderr, flush=True) + print("%s Solver Error: %s" % (self.timestamp(), stmt), flush=True) if self.solver != "dummy": self.p_close() sys.exit(1) @@ -645,13 +646,43 @@ class SmtIo: print("\b \b" * num_bs, end="", file=sys.stderr) sys.stderr.flush() + else: + count = 0 + while self.p_poll(60): + count += 1 + msg = None + + if count == 1: + msg = "1 minute" + + elif count in [5, 10, 15, 30]: + msg = "%d minutes" % count + + elif count == 60: + msg = "1 hour" + + elif count % 60 == 0: + msg = "%d hours" % (count // 60) + + if msg is not None: + print("%s waiting for solver (%s)" % (self.timestamp(), msg), flush=True) + result = self.read() - assert result in ["sat", "unsat"] if self.debug_file: print("(set-info :status %s)" % result, file=self.debug_file) print("(check-sat)", file=self.debug_file) self.debug_file.flush() + + if result not in ["sat", "unsat"]: + if result == "": + print("%s Unexpected EOF response from solver." % (self.timestamp()), flush=True) + else: + print("%s Unexpected response from solver: %s" % (self.timestamp(), result), flush=True) + if self.solver != "dummy": + self.p_close() + sys.exit(1) + return result def parse(self, stmt): @@ -706,6 +737,9 @@ class SmtIo: return h def bv2bin(self, v): + if type(v) is list and len(v) == 3 and v[0] == "_" and v[1].startswith("bv"): + x, n = int(v[1][2:]), int(v[2]) + return "".join("1" if (x & (1 << i)) else "0" for i in range(n-1, -1, -1)) if v == "true": return "1" if v == "false": return "0" if v.startswith("#b"): @@ -981,7 +1015,7 @@ class MkVcd: for i in range(len(uipath)): uipath[i] = re.sub(r"\[([^\]]*)\]", r"<\1>", uipath[i]) - while uipath[:len(scope)] != scope[:-1]: + while uipath[:len(scope)] != scope: print("$upscope $end", file=self.f) scope = scope[:-1] |