aboutsummaryrefslogtreecommitdiffstats
path: root/backends/smt2
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2017-02-26 21:26:32 +0100
committerClifford Wolf <clifford@clifford.at>2017-02-26 21:26:32 +0100
commit22035622689ce6fee2236c0e41b66e94c75d21bc (patch)
tree073809fd3faedff3e48ec19839250940435a719f /backends/smt2
parent80ecd7a26f0a7fbf742d176d5aacfed6a7d49d17 (diff)
downloadyosys-22035622689ce6fee2236c0e41b66e94c75d21bc.tar.gz
yosys-22035622689ce6fee2236c0e41b66e94c75d21bc.tar.bz2
yosys-22035622689ce6fee2236c0e41b66e94c75d21bc.zip
Add smtbmc support for memory vcd dumping
Diffstat (limited to 'backends/smt2')
-rw-r--r--backends/smt2/smtbmc.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py
index 97a552c52..b587981bc 100644
--- a/backends/smt2/smtbmc.py
+++ b/backends/smt2/smtbmc.py
@@ -550,11 +550,109 @@ def write_vcd_trace(steps_start, steps_stop, index):
vcd.add_net([topmod] + netpath, smt.net_width(topmod, netpath))
path_list.append(netpath)
+ mem_trace_data = dict()
+ for mempath in sorted(smt.hiermems(topmod)):
+ abits, width, rports, wports = smt.mem_info(topmod, mempath)
+
+ expr_id = list()
+ expr_list = list()
+ for i in range(steps_start, steps_stop):
+ for j in range(rports):
+ expr_id.append(('R', i-steps_start, j, 'A'))
+ expr_id.append(('R', i-steps_start, j, 'D'))
+ expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dA" % j))
+ expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "R%dD" % j))
+ for j in range(wports):
+ expr_id.append(('W', i-steps_start, j, 'A'))
+ expr_id.append(('W', i-steps_start, j, 'D'))
+ expr_id.append(('W', i-steps_start, j, 'M'))
+ expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dA" % j))
+ expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dD" % j))
+ expr_list.append(smt.mem_expr(topmod, "s%d" % i, mempath, "W%dM" % j))
+
+ rdata = list()
+ wdata = list()
+ addrs = set()
+
+ for eid, edat in zip(expr_id, smt.get_list(expr_list)):
+ t, i, j, f = eid
+
+ if t == 'R':
+ c = rdata
+ elif t == 'W':
+ c = wdata
+ else:
+ assert False
+
+ while len(c) <= i:
+ c.append(list())
+ c = c[i]
+
+ while len(c) <= j:
+ c.append(dict())
+ c = c[j]
+
+ c[f] = smt.bv2bin(edat)
+
+ if f == 'A':
+ addrs.add(c[f])
+
+ for addr in addrs:
+ tdata = list()
+ data = ["x"] * width
+ gotread = False
+
+ assert len(rdata) == len(wdata)
+
+ for i in range(len(wdata)):
+ if not gotread:
+ for j_data in rdata[i]:
+ if j_data["A"] == addr:
+ data = list(j_data["D"])
+ gotread = True
+ break
+
+ if gotread:
+ buf = data[:]
+ for i in reversed(range(len(tdata))):
+ for k in range(width):
+ if tdata[i][k] == "x":
+ tdata[i][k] = buf[k]
+ else:
+ buf[k] = tdata[i][k]
+
+ tdata.append(data[:])
+
+ for j_data in wdata[i]:
+ if j_data["A"] != addr:
+ continue
+
+ D = j_data["D"]
+ M = j_data["M"]
+
+ for k in range(width):
+ if M[k] == "1":
+ data[k] = D[k]
+
+ assert len(tdata) == len(rdata)
+
+ netpath = mempath[:]
+ netpath[-1] += "<%d>" % int(addr, 2)
+ vcd.add_net([topmod] + netpath, width)
+
+ for i in range(steps_start, steps_stop):
+ if i not in mem_trace_data:
+ mem_trace_data[i] = list()
+ mem_trace_data[i].append((netpath, "".join(tdata[i-steps_start])))
+
for i in range(steps_start, steps_stop):
vcd.set_time(i)
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)
+ if i in mem_trace_data:
+ for path, value in mem_trace_data[i]:
+ vcd.set_net([topmod] + path, value)
vcd.set_time(steps_stop)