rocket-engine 0.0.2b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rocket_engine/__init__.py +8 -0
- rocket_engine/__main__.py +12 -0
- rocket_engine/adapters/README.md +54 -0
- rocket_engine/adapters/__init__.py +7 -0
- rocket_engine/adapters/api.py +39 -0
- rocket_engine/adapters/base.py +46 -0
- rocket_engine/adapters/cace/__init__.py +163 -0
- rocket_engine/adapters/circulax/README.md +10 -0
- rocket_engine/adapters/circulax/__init__.py +112 -0
- rocket_engine/adapters/circulax/_driver.py +190 -0
- rocket_engine/adapters/circulax/adapter.py +538 -0
- rocket_engine/adapters/circulax/results.py +291 -0
- rocket_engine/adapters/cli/README.md +34 -0
- rocket_engine/adapters/cli/__init__.py +305 -0
- rocket_engine/adapters/connectivity/__init__.py +196 -0
- rocket_engine/adapters/connectivity/results.py +214 -0
- rocket_engine/adapters/cosim/README.md +9 -0
- rocket_engine/adapters/cosim/__init__.py +1390 -0
- rocket_engine/adapters/cosim/results.py +214 -0
- rocket_engine/adapters/devsim/__init__.py +171 -0
- rocket_engine/adapters/digital_flow/README.md +9 -0
- rocket_engine/adapters/digital_flow/__init__.py +1121 -0
- rocket_engine/adapters/digital_flow/results.py +227 -0
- rocket_engine/adapters/digital_flow/state.py +462 -0
- rocket_engine/adapters/drc/README.klayout.md +7 -0
- rocket_engine/adapters/drc/README.md +7 -0
- rocket_engine/adapters/drc/__init__.py +1 -0
- rocket_engine/adapters/drc/klayout.py +952 -0
- rocket_engine/adapters/drc/magic.py +287 -0
- rocket_engine/adapters/drc/results.py +184 -0
- rocket_engine/adapters/drc/results_kl.py +188 -0
- rocket_engine/adapters/elmer/__init__.py +163 -0
- rocket_engine/adapters/envelope.py +120 -0
- rocket_engine/adapters/equivalence/__init__.py +156 -0
- rocket_engine/adapters/errors.py +181 -0
- rocket_engine/adapters/extract_magic/README.md +15 -0
- rocket_engine/adapters/extract_magic/__init__.py +425 -0
- rocket_engine/adapters/extract_magic/results.py +209 -0
- rocket_engine/adapters/formal_sby/README.md +7 -0
- rocket_engine/adapters/formal_sby/__init__.py +773 -0
- rocket_engine/adapters/formal_sby/formal_edge.py +195 -0
- rocket_engine/adapters/formal_sby/results.py +185 -0
- rocket_engine/adapters/gdsfactory/__init__.py +194 -0
- rocket_engine/adapters/gdsfactory/_driver.py +459 -0
- rocket_engine/adapters/gdsfactory/adapter.py +609 -0
- rocket_engine/adapters/gdsfactory/results.py +181 -0
- rocket_engine/adapters/hdl_sim/README.md +7 -0
- rocket_engine/adapters/hdl_sim/__init__.py +369 -0
- rocket_engine/adapters/hdl_sim/ghdl.py +155 -0
- rocket_engine/adapters/hdl_sim/results.py +178 -0
- rocket_engine/adapters/hdl_sim/verilator.py +167 -0
- rocket_engine/adapters/http/README.md +15 -0
- rocket_engine/adapters/http/__init__.py +458 -0
- rocket_engine/adapters/http/events.py +63 -0
- rocket_engine/adapters/ipc/README.md +9 -0
- rocket_engine/adapters/ipc/__init__.py +111 -0
- rocket_engine/adapters/lvs_netgen/README.md +20 -0
- rocket_engine/adapters/lvs_netgen/__init__.py +889 -0
- rocket_engine/adapters/lvs_netgen/results.py +168 -0
- rocket_engine/adapters/mcp/README.md +19 -0
- rocket_engine/adapters/mcp/__init__.py +85 -0
- rocket_engine/adapters/mcp/api-schema.json +6107 -0
- rocket_engine/adapters/mcp/pull.py +246 -0
- rocket_engine/adapters/mcp/server.py +794 -0
- rocket_engine/adapters/meep/__init__.py +167 -0
- rocket_engine/adapters/meow/README.md +7 -0
- rocket_engine/adapters/meow/__init__.py +190 -0
- rocket_engine/adapters/meow/_driver.py +227 -0
- rocket_engine/adapters/meow/_envelope.py +108 -0
- rocket_engine/adapters/meow/adapter.py +491 -0
- rocket_engine/adapters/meow/results.py +218 -0
- rocket_engine/adapters/mutation/__init__.py +192 -0
- rocket_engine/adapters/ngspice/README.md +28 -0
- rocket_engine/adapters/ngspice/__init__.py +627 -0
- rocket_engine/adapters/ngspice/results.py +215 -0
- rocket_engine/adapters/postlayout/README.md +28 -0
- rocket_engine/adapters/postlayout/__init__.py +17 -0
- rocket_engine/adapters/postlayout/adapter.py +1062 -0
- rocket_engine/adapters/postlayout/results.py +330 -0
- rocket_engine/adapters/postlayout/translate.py +71 -0
- rocket_engine/adapters/profile.py +220 -0
- rocket_engine/adapters/sax/README.md +23 -0
- rocket_engine/adapters/sax/__init__.py +516 -0
- rocket_engine/adapters/sax/_driver.py +148 -0
- rocket_engine/adapters/sax/results.py +291 -0
- rocket_engine/adapters/stdio_console.py +1151 -0
- rocket_engine/adapters/syntax/README.md +5 -0
- rocket_engine/adapters/syntax/__init__.py +366 -0
- rocket_engine/adapters/syntax/results.py +181 -0
- rocket_engine/adapters/synth_yosys/README.md +7 -0
- rocket_engine/adapters/synth_yosys/__init__.py +655 -0
- rocket_engine/adapters/synth_yosys/amaranth.py +120 -0
- rocket_engine/adapters/synth_yosys/ghdl.py +128 -0
- rocket_engine/adapters/synth_yosys/results.py +173 -0
- rocket_engine/adapters/timing_sta/README.md +9 -0
- rocket_engine/adapters/timing_sta/__init__.py +726 -0
- rocket_engine/adapters/view_sync/__init__.py +185 -0
- rocket_engine/adapters/view_sync/results.py +189 -0
- rocket_engine/adapters/vlsir/__init__.py +142 -0
- rocket_engine/adapters/xschem/__init__.py +440 -0
- rocket_engine/adapters/xschem/deck.py +266 -0
- rocket_engine/clients/__init__.py +5 -0
- rocket_engine/clients/runtime.py +255 -0
- rocket_engine/composition.py +2279 -0
- rocket_engine/execution/README.md +30 -0
- rocket_engine/execution/__init__.py +150 -0
- rocket_engine/execution/apig/__init__.py +1 -0
- rocket_engine/execution/apig/pool.py +463 -0
- rocket_engine/execution/apig/submit.py +124 -0
- rocket_engine/execution/block_runs_scope.py +479 -0
- rocket_engine/execution/coalesce.py +414 -0
- rocket_engine/execution/console/__init__.py +1 -0
- rocket_engine/execution/console/apply_session.py +318 -0
- rocket_engine/execution/console/lifecycle.py +265 -0
- rocket_engine/execution/dispatch.py +205 -0
- rocket_engine/execution/errors.py +31 -0
- rocket_engine/execution/ports.py +797 -0
- rocket_engine/execution/pyexec/__init__.py +1 -0
- rocket_engine/execution/pyexec/apply_context.py +547 -0
- rocket_engine/execution/pyexec/approvals.py +173 -0
- rocket_engine/execution/pyexec/runner.py +404 -0
- rocket_engine/execution/pyexec/support.py +464 -0
- rocket_engine/execution/python_exec.py +897 -0
- rocket_engine/execution/queue.py +85 -0
- rocket_engine/execution/replay_safe.py +601 -0
- rocket_engine/execution/routing/__init__.py +1 -0
- rocket_engine/execution/routing/calls.py +364 -0
- rocket_engine/execution/routing/namespace.py +785 -0
- rocket_engine/execution/routing/ports.py +102 -0
- rocket_engine/execution/routing/tools.py +346 -0
- rocket_engine/execution/runner.py +311 -0
- rocket_engine/execution/runtime.py +1149 -0
- rocket_engine/execution/service.py +279 -0
- rocket_engine/execution/worker.py +464 -0
- rocket_engine/interfaces/README.md +26 -0
- rocket_engine/interfaces/__init__.py +58 -0
- rocket_engine/interfaces/apig_assets.py +407 -0
- rocket_engine/interfaces/celllink.py +461 -0
- rocket_engine/interfaces/documents.py +92 -0
- rocket_engine/interfaces/envelopes.py +131 -0
- rocket_engine/interfaces/errors.py +16 -0
- rocket_engine/interfaces/layout.py +410 -0
- rocket_engine/interfaces/layout_schema.yaml +278 -0
- rocket_engine/interfaces/paths.py +223 -0
- rocket_engine/interfaces/pdks.py +550 -0
- rocket_engine/interfaces/ports.py +72 -0
- rocket_engine/interfaces/references.py +115 -0
- rocket_engine/interfaces/refs.py +85 -0
- rocket_engine/interfaces/runparams.py +304 -0
- rocket_engine/interfaces/setup.py +552 -0
- rocket_engine/interfaces/setup_catalogue.yaml +243 -0
- rocket_engine/interfaces/setup_probes.py +66 -0
- rocket_engine/interfaces/vocabulary.py +58 -0
- rocket_engine/interfaces/yaml_dump.py +31 -0
- rocket_engine/library/README.md +22 -0
- rocket_engine/library/__init__.py +13 -0
- rocket_engine/library/apig_catalog.py +371 -0
- rocket_engine/library/catalog.py +185 -0
- rocket_engine/library/errors.py +16 -0
- rocket_engine/mutate/__init__.py +776 -0
- rocket_engine/mutate/operators.py +700 -0
- rocket_engine/ops/__init__.py +1 -0
- rocket_engine/ops/deferred.py +279 -0
- rocket_engine/ops/editors.py +404 -0
- rocket_engine/ops/evidence.py +194 -0
- rocket_engine/ops/gates.py +262 -0
- rocket_engine/ops/ports.py +76 -0
- rocket_engine/ops/queries.py +417 -0
- rocket_engine/ops/runs.py +553 -0
- rocket_engine/ops/submit.py +614 -0
- rocket_engine/project/README.md +27 -0
- rocket_engine/project/__init__.py +6 -0
- rocket_engine/project/canvas/__init__.py +55 -0
- rocket_engine/project/canvas/compile.py +109 -0
- rocket_engine/project/canvas/integrate.py +48 -0
- rocket_engine/project/canvas/schema.py +241 -0
- rocket_engine/project/canvas/templates.py +46 -0
- rocket_engine/project/canvas/validate.py +603 -0
- rocket_engine/project/edit/__init__.py +5 -0
- rocket_engine/project/edit/cas.py +87 -0
- rocket_engine/project/edit/transactions.py +282 -0
- rocket_engine/project/errors.py +16 -0
- rocket_engine/project/frontend13.py +685 -0
- rocket_engine/project/geometry/__init__.py +23 -0
- rocket_engine/project/geometry/ops.py +451 -0
- rocket_engine/project/geometry/snap.py +103 -0
- rocket_engine/project/ip/__init__.py +1 -0
- rocket_engine/project/ip/blocks.py +195 -0
- rocket_engine/project/ip/entry.schema.json +78 -0
- rocket_engine/project/ip/lifecycle.py +402 -0
- rocket_engine/project/ip/verbs.py +123 -0
- rocket_engine/project/layers/__init__.py +6 -0
- rocket_engine/project/layers/bindings.py +115 -0
- rocket_engine/project/layers/catalog.py +228 -0
- rocket_engine/project/layers/presets.py +43 -0
- rocket_engine/project/ledger/__init__.py +1 -0
- rocket_engine/project/ledger/docs.py +167 -0
- rocket_engine/project/ledger/entities.py +176 -0
- rocket_engine/project/ledger/events.py +29 -0
- rocket_engine/project/ledger/runs.py +257 -0
- rocket_engine/project/ledger/shared.py +174 -0
- rocket_engine/project/ledger/snapshots.py +385 -0
- rocket_engine/project/ledger/wires.py +552 -0
- rocket_engine/project/process/__init__.py +14 -0
- rocket_engine/project/process/model.py +193 -0
- rocket_engine/project/process/recipes.py +121 -0
- rocket_engine/project/schematic/__init__.py +1 -0
- rocket_engine/project/schematic/hierarchy.py +312 -0
- rocket_engine/project/schematic/instances.py +393 -0
- rocket_engine/project/schematic/sheets.py +198 -0
- rocket_engine/project/service.py +2941 -0
- rocket_engine/project/symbols/__init__.py +1 -0
- rocket_engine/project/symbols/cells.py +324 -0
- rocket_engine/project/symbols/linkage.py +356 -0
- rocket_engine/project/symbols/symbols.py +352 -0
- rocket_engine/project/templates/__init__.py +303 -0
- rocket_engine/project/templates/errors.py +25 -0
- rocket_engine/project/testbench/__init__.py +49 -0
- rocket_engine/project/testbench/blocks.py +619 -0
- rocket_engine/project/testbench/templates.py +134 -0
- rocket_engine/stores/README.md +12 -0
- rocket_engine/stores/__init__.py +6 -0
- rocket_engine/stores/ecs.py +1508 -0
- rocket_engine/stores/layers.py +1023 -0
- rocket_engine/stores/settings.py +1188 -0
- rocket_engine/stores/wireplace.py +1324 -0
- rocket_engine/workflows/README.md +18 -0
- rocket_engine/workflows/__init__.py +53 -0
- rocket_engine/workflows/capability_plan.py +102 -0
- rocket_engine/workflows/completion.py +228 -0
- rocket_engine/workflows/connectgraph.py +734 -0
- rocket_engine/workflows/connectgraph_emit.py +336 -0
- rocket_engine/workflows/gates.py +144 -0
- rocket_engine/workflows/photonic_wire.py +76 -0
- rocket_engine/workflows/stages.py +324 -0
- rocket_engine/workflows/viewsync.py +399 -0
- rocket_engine-0.0.2b1.dist-info/METADATA +200 -0
- rocket_engine-0.0.2b1.dist-info/RECORD +241 -0
- rocket_engine-0.0.2b1.dist-info/WHEEL +4 -0
- rocket_engine-0.0.2b1.dist-info/entry_points.txt +2 -0
- rocket_engine-0.0.2b1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""Connectgraph solver adapter: run_connectivity/run_erc, no subprocess.
|
|
2
|
+
|
|
3
|
+
Pure-Python ToolAdapter over the shared extraction plus raw-IR
|
|
4
|
+
emitters. run_connectivity extracts the graph, emits the requested
|
|
5
|
+
netlists, and reports connectivity findings (shorts fail, the rest
|
|
6
|
+
warn); run_erc judges the same findings with unconnected pins
|
|
7
|
+
escalated to errors. Every net name in findings and netlists flows
|
|
8
|
+
from the shared `Connectivity.net_name` authority.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from ...interfaces import ToolAdapter
|
|
12
|
+
from ...workflows.connectgraph import (
|
|
13
|
+
RULE_UNCONNECTED_PIN,
|
|
14
|
+
ConnectGraphError,
|
|
15
|
+
erc_findings,
|
|
16
|
+
prepare_netlist_structs,
|
|
17
|
+
)
|
|
18
|
+
from ...workflows.connectgraph_emit import LANGUAGES, emit_netlists, to_raw_ir
|
|
19
|
+
from ..errors import AdapterError
|
|
20
|
+
|
|
21
|
+
OPERATIONS = ("run_connectivity", "run_erc")
|
|
22
|
+
TOOL = "connectgraph"
|
|
23
|
+
|
|
24
|
+
CONNECTIVITY_POLICY = {RULE_UNCONNECTED_PIN: "warning"}
|
|
25
|
+
ERC_POLICY = {RULE_UNCONNECTED_PIN: "error"}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConnectivityAdapter(ToolAdapter):
|
|
29
|
+
"""Shared-graph connectivity checks plus netlist emission.
|
|
30
|
+
|
|
31
|
+
Serves run_connectivity and run_erc with deck.tool
|
|
32
|
+
`connectgraph` (the only tool). Extraction, naming, and emission
|
|
33
|
+
all run in-process; there is no tool to resolve and no timeout.
|
|
34
|
+
|
|
35
|
+
Job keys:
|
|
36
|
+
schematic (required): Schematic record (see
|
|
37
|
+
workflows.connectgraph for the shape).
|
|
38
|
+
languages: Netlist languages for run_connectivity
|
|
39
|
+
(default all of spice, verilog, vhdl).
|
|
40
|
+
run_key: Explicit extraction-cache key; uncached when omitted.
|
|
41
|
+
deck: Optional mapping; deck.tool must be connectgraph here.
|
|
42
|
+
|
|
43
|
+
Caution: run_erc fails on unconnected pins while
|
|
44
|
+
run_connectivity only warns — same findings, different
|
|
45
|
+
policy; read the verdict, never the exit path.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def capabilities(self, target):
|
|
49
|
+
"""Report the served operations and tool name.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
target: Target the capabilities are reported for
|
|
53
|
+
(accepted, unused — one schematic per job).
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Capability mapping with operations and tool.
|
|
57
|
+
"""
|
|
58
|
+
return {"operations": list(OPERATIONS), "tool": TOOL}
|
|
59
|
+
|
|
60
|
+
def preflight(self, job):
|
|
61
|
+
"""Check operation, tool hint, schematic, and languages.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
job: Solver job with operation run_connectivity or
|
|
65
|
+
run_erc plus schematic and language inputs.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Checked mapping with operation, schematic, languages,
|
|
69
|
+
and run_key.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
AdapterError: unsupported_operation for another
|
|
73
|
+
operation or deck tool, invalid_command for a
|
|
74
|
+
missing schematic or an unknown language.
|
|
75
|
+
"""
|
|
76
|
+
if job.get("operation") not in OPERATIONS:
|
|
77
|
+
raise AdapterError(
|
|
78
|
+
"unsupported_operation",
|
|
79
|
+
f"Connectivity handles {', '.join(OPERATIONS)}, "
|
|
80
|
+
f"got {job.get('operation')}.",
|
|
81
|
+
)
|
|
82
|
+
hint = (job.get("deck") or {}).get("tool")
|
|
83
|
+
if hint is not None and hint != TOOL:
|
|
84
|
+
raise AdapterError(
|
|
85
|
+
"unsupported_operation",
|
|
86
|
+
f"No {job.get('operation')} solver for deck tool: {hint}.",
|
|
87
|
+
)
|
|
88
|
+
schematic = job.get("schematic")
|
|
89
|
+
if not isinstance(schematic, dict):
|
|
90
|
+
raise AdapterError(
|
|
91
|
+
"invalid_command", "run_connectivity needs a schematic mapping."
|
|
92
|
+
)
|
|
93
|
+
languages = job.get("languages", list(LANGUAGES))
|
|
94
|
+
if not isinstance(languages, list) or any(
|
|
95
|
+
language not in LANGUAGES for language in languages
|
|
96
|
+
):
|
|
97
|
+
raise AdapterError(
|
|
98
|
+
"invalid_command",
|
|
99
|
+
f"languages must be a list from {list(LANGUAGES)}, "
|
|
100
|
+
f"got {job.get('languages')!r}.",
|
|
101
|
+
)
|
|
102
|
+
return {
|
|
103
|
+
"operation": job.get("operation"),
|
|
104
|
+
"schematic": schematic,
|
|
105
|
+
"languages": list(languages),
|
|
106
|
+
"run_key": job.get("run_key"),
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
def execute(self, job):
|
|
110
|
+
"""Extract the graph, emit netlists, collect ERC findings.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
job: Solver job with operation run_connectivity or
|
|
114
|
+
run_erc plus schematic and language inputs.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Native output with exit_code, findings, netlists, net
|
|
118
|
+
table, counts, and a one-line log.
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
AdapterError: invalid_command for a malformed
|
|
122
|
+
schematic, plus the preflight codes (execute
|
|
123
|
+
re-checks first).
|
|
124
|
+
"""
|
|
125
|
+
checked = self.preflight(job)
|
|
126
|
+
try:
|
|
127
|
+
structs = prepare_netlist_structs(
|
|
128
|
+
checked["schematic"], run_key=checked["run_key"]
|
|
129
|
+
)
|
|
130
|
+
except ConnectGraphError as exc:
|
|
131
|
+
raise AdapterError("invalid_command", str(exc)) from exc
|
|
132
|
+
policy = ERC_POLICY if checked["operation"] == "run_erc" else CONNECTIVITY_POLICY
|
|
133
|
+
findings = erc_findings(structs.connectivity, policy=policy)
|
|
134
|
+
try:
|
|
135
|
+
raw = to_raw_ir(structs)
|
|
136
|
+
netlists = emit_netlists(raw, languages=checked["languages"])
|
|
137
|
+
except ConnectGraphError as exc:
|
|
138
|
+
raise AdapterError("invalid_command", str(exc)) from exc
|
|
139
|
+
nets = [net["name"] for net in raw["nets"]]
|
|
140
|
+
errors = sum(1 for f in findings if f["severity"] == "error")
|
|
141
|
+
return {
|
|
142
|
+
"exit_code": 0,
|
|
143
|
+
"operation": checked["operation"],
|
|
144
|
+
"findings": findings,
|
|
145
|
+
"netlists": netlists,
|
|
146
|
+
"nets": nets,
|
|
147
|
+
"net_count": len(nets),
|
|
148
|
+
"instance_count": len(raw["instances"]),
|
|
149
|
+
"skipped": raw["skipped"],
|
|
150
|
+
"log": (
|
|
151
|
+
f"{checked['operation']}: {len(nets)} nets, "
|
|
152
|
+
f"{len(raw['instances'])} instances, {errors} errors"
|
|
153
|
+
),
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
def parse(self, native_output):
|
|
157
|
+
"""Normalize findings into violations; netlists ride measurements.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
native_output: Native output from execute.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
{total, violations[]} plus measurements with netlists,
|
|
164
|
+
the net table, counts, and skipped instances.
|
|
165
|
+
|
|
166
|
+
Raises:
|
|
167
|
+
AdapterError: runner_unavailable when the output has
|
|
168
|
+
no findings list.
|
|
169
|
+
"""
|
|
170
|
+
findings = native_output.get("findings")
|
|
171
|
+
if not isinstance(findings, list):
|
|
172
|
+
raise AdapterError(
|
|
173
|
+
"runner_unavailable", "connectgraph output has no findings list."
|
|
174
|
+
)
|
|
175
|
+
violations = []
|
|
176
|
+
for finding in findings:
|
|
177
|
+
violations.append(
|
|
178
|
+
{
|
|
179
|
+
"rule": finding["rule"],
|
|
180
|
+
"severity": finding["severity"],
|
|
181
|
+
"message": finding.get("message", finding["rule"]),
|
|
182
|
+
"net": finding.get("net"),
|
|
183
|
+
"net_id": finding.get("net_id"),
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
return {
|
|
187
|
+
"total": len(violations),
|
|
188
|
+
"violations": violations,
|
|
189
|
+
"measurements": {
|
|
190
|
+
"netlists": native_output.get("netlists", {}),
|
|
191
|
+
"nets": native_output.get("nets", []),
|
|
192
|
+
"net_count": native_output.get("net_count", 0),
|
|
193
|
+
"instance_count": native_output.get("instance_count", 0),
|
|
194
|
+
"skipped": native_output.get("skipped", []),
|
|
195
|
+
},
|
|
196
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""Connectivity v1 normalizer: v0 parse output to a ResultBundle.
|
|
2
|
+
|
|
3
|
+
Maps the ``run_connectivity``/``run_erc`` parse shape
|
|
4
|
+
(``violations[]`` with rule, severity, message, and net plus a
|
|
5
|
+
measurements mapping with the net inventory and counts) onto a
|
|
6
|
+
typed findings table, a nets table, bound views, count
|
|
7
|
+
measurements, and findings. Pure function of the parsed output:
|
|
8
|
+
no I/O, no tool calls, deterministic ids derived from the run
|
|
9
|
+
id.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
TASK = "run_connectivity"
|
|
13
|
+
|
|
14
|
+
_DIAG_CAP = 240
|
|
15
|
+
|
|
16
|
+
_SEVERITY = {"error": "error", "warning": "warning"}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _cap(text):
|
|
20
|
+
"""Cap one diagnostic string at the bundle prose limit.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
text: Raw diagnostic text, possibly unbounded tool prose.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
The text unchanged when short, else truncated with an
|
|
27
|
+
ellipsis marker.
|
|
28
|
+
"""
|
|
29
|
+
text = text if isinstance(text, str) else str(text)
|
|
30
|
+
if len(text) <= _DIAG_CAP:
|
|
31
|
+
return text
|
|
32
|
+
return text[: _DIAG_CAP - 3] + "..."
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _quantity(value, unit):
|
|
36
|
+
"""Build one v1 Quantity, mapping unitless to dimensionless.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
value: Numeric value.
|
|
40
|
+
unit: Unit string, possibly empty for unitless measures.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Quantity mapping with an explicit unit.
|
|
44
|
+
"""
|
|
45
|
+
return {"value": float(value), "unit": unit if unit else "1"}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _provenance(project_id, run_id, tools, provenance):
|
|
49
|
+
"""Build ResultProvenance, defaulting to a placeholder closure.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
project_id: Project the run belongs to.
|
|
53
|
+
run_id: Run the bundle describes.
|
|
54
|
+
tools: Tool ingredient mappings (id, version, digest?).
|
|
55
|
+
provenance: Full provenance mapping when the caller has
|
|
56
|
+
one; a deterministic placeholder otherwise.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Provenance mapping valid against the v1 schema.
|
|
60
|
+
"""
|
|
61
|
+
if provenance is not None:
|
|
62
|
+
return provenance
|
|
63
|
+
ref = {"scope": "project", "id": project_id, "revision": "r1"}
|
|
64
|
+
return {
|
|
65
|
+
"snapshot": dict(ref),
|
|
66
|
+
"input_lock": dict(ref),
|
|
67
|
+
"closure_hash": "0" * 64,
|
|
68
|
+
"tools": [
|
|
69
|
+
{
|
|
70
|
+
"id": item["id"],
|
|
71
|
+
"version": item.get("version", ""),
|
|
72
|
+
"digest": item.get("digest", "0" * 64),
|
|
73
|
+
}
|
|
74
|
+
for item in tools
|
|
75
|
+
],
|
|
76
|
+
"parents": [],
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def normalize(parsed, *, run_id, project_id="project", target=None,
|
|
81
|
+
tools=(), provenance=None):
|
|
82
|
+
"""Normalize one connectivity parse output to a v1 ResultBundle.
|
|
83
|
+
|
|
84
|
+
Finding rows become a table dataset (rule, severity, message,
|
|
85
|
+
net) and the net inventory a second table; net and instance
|
|
86
|
+
counts ride PASS measurements. Every violation also becomes a
|
|
87
|
+
finding with a capped message.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
parsed: v0 parse mapping with ``violations[]`` and a
|
|
91
|
+
measurements mapping.
|
|
92
|
+
run_id: Run the bundle describes (anchors all ids).
|
|
93
|
+
project_id: Project the run belongs to.
|
|
94
|
+
target: v1 target mapping; project kind by default.
|
|
95
|
+
tools: Tool ingredient mappings for provenance.
|
|
96
|
+
provenance: Full provenance mapping when the caller has
|
|
97
|
+
one; a deterministic placeholder otherwise.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Schema-valid ResultBundle mapping.
|
|
101
|
+
"""
|
|
102
|
+
violations = parsed.get("violations") or []
|
|
103
|
+
measured = parsed.get("measurements") or {}
|
|
104
|
+
nets = measured.get("nets") or []
|
|
105
|
+
findings_id = f"{run_id}:dataset:findings"
|
|
106
|
+
nets_id = f"{run_id}:dataset:nets"
|
|
107
|
+
datasets = [
|
|
108
|
+
{
|
|
109
|
+
"id": findings_id,
|
|
110
|
+
"kind": "table",
|
|
111
|
+
"row_count": len(violations),
|
|
112
|
+
"columns": [
|
|
113
|
+
{
|
|
114
|
+
"id": f"{findings_id}:rule",
|
|
115
|
+
"name": "rule",
|
|
116
|
+
"dtype": "utf8",
|
|
117
|
+
"unit": "1",
|
|
118
|
+
"data": [v.get("rule", "") for v in violations],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": f"{findings_id}:severity",
|
|
122
|
+
"name": "severity",
|
|
123
|
+
"dtype": "utf8",
|
|
124
|
+
"unit": "1",
|
|
125
|
+
"data": [v.get("severity", "") for v in violations],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": f"{findings_id}:message",
|
|
129
|
+
"name": "message",
|
|
130
|
+
"dtype": "utf8",
|
|
131
|
+
"unit": "1",
|
|
132
|
+
"data": [_cap(v.get("message", "")) for v in violations],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": f"{findings_id}:net",
|
|
136
|
+
"name": "net",
|
|
137
|
+
"dtype": "utf8",
|
|
138
|
+
"unit": "1",
|
|
139
|
+
"data": [str(v.get("net") or "") for v in violations],
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
"conditions": [],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": nets_id,
|
|
146
|
+
"kind": "table",
|
|
147
|
+
"row_count": len(nets),
|
|
148
|
+
"columns": [
|
|
149
|
+
{
|
|
150
|
+
"id": f"{nets_id}:net",
|
|
151
|
+
"name": "net",
|
|
152
|
+
"dtype": "utf8",
|
|
153
|
+
"unit": "1",
|
|
154
|
+
"data": [str(net) for net in nets],
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
"conditions": [],
|
|
158
|
+
},
|
|
159
|
+
]
|
|
160
|
+
views = [
|
|
161
|
+
{
|
|
162
|
+
"id": f"{run_id}:view:findings",
|
|
163
|
+
"kind": "table",
|
|
164
|
+
"dataset_id": findings_id,
|
|
165
|
+
"name": "connectivity findings",
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": f"{run_id}:view:nets",
|
|
169
|
+
"kind": "table",
|
|
170
|
+
"dataset_id": nets_id,
|
|
171
|
+
"name": "net inventory",
|
|
172
|
+
},
|
|
173
|
+
]
|
|
174
|
+
measurements = []
|
|
175
|
+
for name in ("net_count", "instance_count"):
|
|
176
|
+
value = measured.get(name)
|
|
177
|
+
if value is None:
|
|
178
|
+
continue
|
|
179
|
+
measurements.append(
|
|
180
|
+
{
|
|
181
|
+
"name": name,
|
|
182
|
+
"value": _quantity(value, "1"),
|
|
183
|
+
"status": "PASS",
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
findings = [
|
|
187
|
+
{
|
|
188
|
+
"id": f"{run_id}:finding:{index}",
|
|
189
|
+
"severity": _SEVERITY.get(v.get("severity"), "info"),
|
|
190
|
+
"code": v.get("rule", "connectivity"),
|
|
191
|
+
"message": _cap(v.get("message", "")),
|
|
192
|
+
}
|
|
193
|
+
for index, v in enumerate(violations)
|
|
194
|
+
]
|
|
195
|
+
return {
|
|
196
|
+
"schema": "rocketeda/results/v1",
|
|
197
|
+
"ref": {"scope": "project", "id": run_id, "revision": "r1"},
|
|
198
|
+
"run_id": run_id,
|
|
199
|
+
"task": TASK,
|
|
200
|
+
"target": dict(target)
|
|
201
|
+
if target is not None
|
|
202
|
+
else {"project_id": project_id, "kind": "project"},
|
|
203
|
+
"state": "complete",
|
|
204
|
+
"freshness": "current",
|
|
205
|
+
"convergence": "not_applicable",
|
|
206
|
+
"provenance": _provenance(project_id, run_id, tools, provenance),
|
|
207
|
+
"datasets": datasets,
|
|
208
|
+
"views": views,
|
|
209
|
+
"measurements": measurements,
|
|
210
|
+
"findings": findings,
|
|
211
|
+
"artifacts": [],
|
|
212
|
+
"logs": [],
|
|
213
|
+
"gaps": [],
|
|
214
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Coupled mixed-signal co-simulation adapter
|
|
2
|
+
|
|
3
|
+
CosimAdapter serves run_cosim. It runs an ngspice transient, samples the analog output into a digital bitstream, passes that stream to the Icarus HDL adapter, and evaluates the combined analog and digital checks.
|
|
4
|
+
|
|
5
|
+
The job supplies its analog sources, digital bench, and loop settings. PDK model references resolve through the PDK store; an invalid or changed model fails preflight. Model-free behavioral jobs can omit the PDK reference.
|
|
6
|
+
|
|
7
|
+
The verdict comes from parsed measurements and digital findings, not the tool exit code. Missing samples or tool failures remain failures or NOT_RUN with a reason. The adapter currently composes its digital half through HdlSimAdapter.
|
|
8
|
+
|
|
9
|
+
See the [SEAM-COSIM report](../../../docs/work/SEAM-COSIM/report.md) for qualification evidence and known limits.
|