sycan.autodraw

sycan.autodraw(circuit, *, top_rail='VDD', bot_rail='VSS', filename=None, optimize=True, iterations=None, seed=0, cost_model='hpwl', res_dir=PosixPath('/home/runner/work/sycan/sycan/res'), reverse_isolated_branches=False, back_annotation=None, max_retries=5, router='astar', collapse=None)[source]

Render circuit to an SVG schematic and return the SVG string.

Parameters:
  • circuit (Circuit | str) – Either a Circuit or a SPICE netlist string.

  • top_rail (str | None) – Net name for the top power rail. Components whose spine touches this net are anchored to the top of the canvas. Pass None to omit the top rail (default: "VDD").

  • bot_rail (str | None) – Net name for the bottom power rail. Components whose spine touches this net are anchored to the bottom of the canvas. The SPICE ground node "0" is always included as a bottom rail. Pass None to omit the bottom rail (default: "VSS").

  • filename (str | Path | None) – Optional path to write the SVG to.

  • optimize (bool) – If True (default), run a simulated-annealing pass over the column order, per-component y position, side-port mirror, and (where topologically free) spine flip. Disable for a deterministic baseline when debugging the placer.

  • iterations (int | None) – Override the SA iteration count. None lets the optimizer scale with circuit size.

  • seed (int) – RNG seed for SA reproducibility.

  • cost_model (str) – "hpwl" (default, fast) — HPWL + bbox-interleave crossings + rail stubs. "real" — actual rectilinear-routed wirelength via grid BFS that knows about component bodies; slower but accounts for routing detours.

  • res_dir (str | Path | None | object) – Folder with per-kind SVG glyphs (res/nmos.svg, res/res.svg, …). Defaults to <repo>/res/ so the bundled symbols render automatically; pass an explicit path to use your own glyph library, or None to disable glyphs and draw the labelled-rect placeholders instead. Components whose kinds are missing from the chosen directory fall back to the rect.

  • reverse_isolated_branches (bool) – If True, the post-SA greedy pass also considers reversing the column direction of each “isolated” branch (one with no rail-anchored desc at either end). The greedy walker in _build_branches picks a direction (top→bot or bot→top) for such branches arbitrarily, but topologically both are equally valid; this move tries the opposite and keeps it when routed wirelength drops. Off by default — current circuits produce no fully-isolated multi-component branches, so this is dormant capability for circuits / branch-builder changes that introduce them.

  • back_annotation (dict[str, Sequence[str]] | None) – Optional mapping of component name → sequence of annotation strings. Each string is rendered as a thin orange line of text on the right-hand side of the matching component, stacked top- to-bottom. Useful for surfacing derived results (operating points, gain numbers, noise figures, …) next to the parts they belong to. Annotations are drawn as the very last layer so they sit on top of every other primitive; collisions with wires or labels are intentionally ignored — the caller chooses what to display.

  • max_retries (int) – Maximum number of fallback render passes triggered when the first pass produces wires that lay collinear on top of one another. Each retry re-runs the SA + routing with the next seed from a fixed sequence (_RETRY_SEEDS); the first pass whose total overlap length is at or below _OVERLAP_TOL is accepted. If every attempt has overlap the lowest-overlap render is returned. Default is 5; pass 0 to disable the loop.

  • collapse (str | Sequence[str] | None) – Optional group path (or sequence of paths) to render as a single placeholder rectangle instead of expanding into its constituent leaves. Each path is the dotted instance chain of a SubCircuit — e.g. "X1" to hide a top-level group, "X1.U1" to hide a nested one. Collapsed groups get a distinctive purple outline and expose one pin per external connection. Unknown paths raise ValueError so callers catch typos early.

  • router (str) – Grid-routing algorithm used at the final routing pass. "dijkstra" (default, historical) is a uniform-cost search with no goal bias. "astar" adds an admissible Manhattan bbox heuristic so the search front is steered toward the target — typically expands fewer cells per net and gives a modest wall-time speedup on larger circuits. Both algorithms share the same edge-cost function (1 + 4·used + clearance + 2·turn), so the routed cost of each net is identical; only tie-broken polyline geometry can differ. Note that the SA cost-evaluation grid (used during placement search) keeps its own BFS/Dijkstra implementation regardless of this flag. See bench/bench_router.py for performance numbers.

Return type:

str