#!/usr/bin/env python3 """Compact ZSCHED trace-vs-model summary. Use after tb_top_psmct32_sh3_zsched regenerates sim/traces/rtl/zsched_*.txt. It compares the current feeder-derived fixed-point model against the RTL issue and fragment traces, split by epoch. """ import contextlib import io import os import sys HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.normpath(os.path.join(HERE, "..")) sys.path.insert(0, HERE) with contextlib.redirect_stdout(io.StringIO()): import diagnose_zsched_persp as D def load_frags(path): out = [] with open(path) as f: for ln in f: p = ln.split() if len(p) >= 5: out.append((int(p[0]), int(p[1]), int(p[2]), int(p[3]), int(p[4], 16) & 0xFFFFFF)) return out def load_issue(path): out = [] with open(path) as f: for ln in f: p = ln.split() if len(p) >= 7: out.append((int(p[0]), int(p[1]), int(p[2]), int(p[3]), int(p[4]), int(p[5]), int(p[6]))) return out def pct(ok, n): return 100.0 * ok / n if n else 0.0 def main(argv): trace_dir = os.path.join(ROOT, "sim", "traces", "rtl") frag_path = argv[1] if len(argv) > 1 else os.path.join(trace_dir, "zsched_frags.txt") issue_path = argv[2] if len(argv) > 2 else os.path.join(trace_dir, "zsched_issue.txt") with contextlib.redirect_stdout(io.StringIO()): _draw_idxs, _tris, _fb, _owner, _emitted, _accepted, model = D.render("zsched") frags = load_frags(frag_path) issue = load_issue(issue_path) n = min(len(model), len(frags), len(issue)) by_ep = {} coord_miss = z_miss = 0 for i in range(n): me = model[i] hwf = frags[i] hwi = issue[i] ep = hwf[0] st = by_ep.setdefault(ep, { "n": 0, "color": 0, "u": 0, "v": 0, "uv": 0, "u_ge512": 0, "v_ge512": 0, }) st["n"] += 1 if me[:3] != hwf[:3]: coord_miss += 1 if abs(me[3] - hwf[3]) > 256: z_miss += 1 if (me[4] & 0xFFFFFF) != hwf[4]: st["color"] += 1 if me[5] != hwi[4]: st["u"] += 1 if me[6] != hwi[5]: st["v"] += 1 if me[5] != hwi[4] or me[6] != hwi[5]: st["uv"] += 1 if hwi[4] >= 512: st["u_ge512"] += 1 if hwi[5] >= 512: st["v_ge512"] += 1 print(f"[uv] model={len(model)} frags={len(frags)} issue={len(issue)} compared={n} coord_miss={coord_miss} z_gt256={z_miss}") for ep in sorted(by_ep): st = by_ep[ep] n_ep = st["n"] u_ok = n_ep - st["u"] v_ok = n_ep - st["v"] uv_ok = n_ep - st["uv"] c_ok = n_ep - st["color"] print( f"[uv] e{ep}: n={n_ep} " f"color_ok={c_ok}/{n_ep} ({pct(c_ok,n_ep):.2f}%) " f"u_ok={u_ok}/{n_ep} ({pct(u_ok,n_ep):.2f}%) " f"v_ok={v_ok}/{n_ep} ({pct(v_ok,n_ep):.2f}%) " f"uv_ok={uv_ok}/{n_ep} ({pct(uv_ok,n_ep):.2f}%) " f"rtl_u_ge512={st['u_ge512']} rtl_v_ge512={st['v_ge512']}" ) if __name__ == "__main__": raise SystemExit(main(sys.argv))