chipgraph 0.1.0__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.
- chipgraph/__init__.py +7 -0
- chipgraph/adapters/__init__.py +1 -0
- chipgraph/adapters/format/__init__.py +6 -0
- chipgraph/adapters/format/__main__.py +16 -0
- chipgraph/adapters/format/_yaml_lines.py +54 -0
- chipgraph/adapters/format/chip_yaml.py +323 -0
- chipgraph/adapters/format/qsoc_contract.py +246 -0
- chipgraph/adapters/llm/__init__.py +58 -0
- chipgraph/adapters/llm/_budget.py +173 -0
- chipgraph/adapters/llm/_errors.py +50 -0
- chipgraph/adapters/llm/_nda.py +30 -0
- chipgraph/adapters/llm/_retry.py +85 -0
- chipgraph/adapters/llm/anthropic.py +247 -0
- chipgraph/adapters/llm/decide_backend.py +179 -0
- chipgraph/adapters/llm/fake.py +87 -0
- chipgraph/adapters/llm/guard.py +68 -0
- chipgraph/adapters/parser/__init__.py +22 -0
- chipgraph/adapters/parser/cocotb.py +304 -0
- chipgraph/adapters/parser/generic_regex.py +75 -0
- chipgraph/adapters/parser/verible.py +55 -0
- chipgraph/adapters/parser/verilator.py +46 -0
- chipgraph/adapters/review/__init__.py +7 -0
- chipgraph/adapters/review/file.py +123 -0
- chipgraph/adapters/review/github.py +886 -0
- chipgraph/adapters/runner/__init__.py +7 -0
- chipgraph/adapters/runner/local.py +122 -0
- chipgraph/adapters/runtime/__init__.py +5 -0
- chipgraph/adapters/runtime/claude_code/__init__.py +24 -0
- chipgraph/adapters/runtime/claude_code/agents.py +158 -0
- chipgraph/adapters/runtime/claude_code/decisions.py +280 -0
- chipgraph/adapters/runtime/claude_code/guarded.py +310 -0
- chipgraph/adapters/runtime/claude_code/isolation.py +482 -0
- chipgraph/adapters/runtime/claude_code/loop.py +342 -0
- chipgraph/adapters/runtime/claude_code/previous.py +419 -0
- chipgraph/adapters/runtime/claude_code/review.py +492 -0
- chipgraph/adapters/runtime/claude_code/runtime.py +192 -0
- chipgraph/adapters/runtime/claude_code/service.py +2285 -0
- chipgraph/adapters/tool/__init__.py +7 -0
- chipgraph/adapters/tool/cmd.py +229 -0
- chipgraph/adapters/tool/edalize.py +773 -0
- chipgraph/adapters/tool/filelist.py +259 -0
- chipgraph/adapters/tool/pyslang.py +485 -0
- chipgraph/adapters/vcs/__init__.py +1 -0
- chipgraph/adapters/vcs/git.py +521 -0
- chipgraph/app/__init__.py +10 -0
- chipgraph/app/baseline.py +339 -0
- chipgraph/app/build.py +332 -0
- chipgraph/app/checks.py +202 -0
- chipgraph/app/context.py +191 -0
- chipgraph/app/errors.py +11 -0
- chipgraph/app/executors.py +79 -0
- chipgraph/app/findings.py +203 -0
- chipgraph/app/ingest.py +523 -0
- chipgraph/checks/__init__.py +52 -0
- chipgraph/checks/_cdc_analyze.py +272 -0
- chipgraph/checks/_cdc_elaborate.py +455 -0
- chipgraph/checks/_common.py +268 -0
- chipgraph/checks/_cross.py +96 -0
- chipgraph/checks/_model.py +64 -0
- chipgraph/checks/_naming_pyslang.py +235 -0
- chipgraph/checks/_naming_rules.py +127 -0
- chipgraph/checks/_xref_syntax.py +260 -0
- chipgraph/checks/cdc_struct.py +235 -0
- chipgraph/checks/connect.py +353 -0
- chipgraph/checks/cross_chip.py +454 -0
- chipgraph/checks/duplicate.py +153 -0
- chipgraph/checks/filelist.py +323 -0
- chipgraph/checks/format.py +268 -0
- chipgraph/checks/generated.py +151 -0
- chipgraph/checks/hardcode.py +233 -0
- chipgraph/checks/layout.py +155 -0
- chipgraph/checks/naming.py +311 -0
- chipgraph/checks/plan_check.py +901 -0
- chipgraph/checks/ports_diff.py +203 -0
- chipgraph/checks/spec_schema.py +277 -0
- chipgraph/checks/style.py +910 -0
- chipgraph/checks/tb_static.py +599 -0
- chipgraph/checks/trace.py +224 -0
- chipgraph/checks/vendor_guard.py +369 -0
- chipgraph/checks/wrap_check.py +486 -0
- chipgraph/cli/__init__.py +1688 -0
- chipgraph/cli/next_steps.py +137 -0
- chipgraph/core/__init__.py +1 -0
- chipgraph/core/config/__init__.py +93 -0
- chipgraph/core/config/defaults.py +14 -0
- chipgraph/core/config/errors.py +32 -0
- chipgraph/core/config/loader.py +766 -0
- chipgraph/core/config/models.py +845 -0
- chipgraph/core/config/templates.py +340 -0
- chipgraph/core/contracts/__init__.py +75 -0
- chipgraph/core/contracts/_paths.py +26 -0
- chipgraph/core/contracts/agent.py +49 -0
- chipgraph/core/contracts/artifact.py +68 -0
- chipgraph/core/contracts/check.py +76 -0
- chipgraph/core/contracts/event.py +70 -0
- chipgraph/core/contracts/export.py +128 -0
- chipgraph/core/contracts/finding.py +171 -0
- chipgraph/core/contracts/gate.py +50 -0
- chipgraph/core/contracts/rule.py +177 -0
- chipgraph/core/contracts/types.py +45 -0
- chipgraph/core/engine/__init__.py +70 -0
- chipgraph/core/engine/agent_rule.py +1362 -0
- chipgraph/core/engine/baseline.py +283 -0
- chipgraph/core/engine/decide.py +462 -0
- chipgraph/core/engine/fanout.py +1358 -0
- chipgraph/core/engine/gate.py +170 -0
- chipgraph/core/engine/graph.py +647 -0
- chipgraph/core/engine/records.py +60 -0
- chipgraph/core/engine/rules.py +92 -0
- chipgraph/core/engine/scheduler.py +637 -0
- chipgraph/core/engine/select.py +1239 -0
- chipgraph/core/engine/targets.py +342 -0
- chipgraph/core/model/__init__.py +98 -0
- chipgraph/core/model/entities.py +244 -0
- chipgraph/core/model/export.py +16 -0
- chipgraph/core/model/ingest.py +693 -0
- chipgraph/core/model/json_value.py +4 -0
- chipgraph/core/model/keys.py +95 -0
- chipgraph/core/model/model.py +153 -0
- chipgraph/core/model/provenance.py +27 -0
- chipgraph/core/model/query.py +583 -0
- chipgraph/core/model/registry.py +80 -0
- chipgraph/core/model/relations.py +61 -0
- chipgraph/core/model/store.py +279 -0
- chipgraph/core/plugin_api/__init__.py +81 -0
- chipgraph/core/plugin_api/local.py +167 -0
- chipgraph/core/plugin_api/pack.py +159 -0
- chipgraph/core/plugin_api/protocols.py +177 -0
- chipgraph/core/plugin_api/registry.py +111 -0
- chipgraph/core/plugin_api/types.py +94 -0
- chipgraph/core/runtime/__init__.py +41 -0
- chipgraph/core/runtime/executor.py +79 -0
- chipgraph/core/runtime/queue.py +565 -0
- chipgraph/core/runtime/roles/__init__.py +91 -0
- chipgraph/core/runtime/roles/data/author.md +41 -0
- chipgraph/core/runtime/roles/data/critic.md +56 -0
- chipgraph/core/runtime/roles/data/planner.md +38 -0
- chipgraph/core/runtime/roles/data/researcher.md +37 -0
- chipgraph/core/runtime/roles/data/rtl-author.md +64 -0
- chipgraph/core/runtime/roles/data/tb-author.md +48 -0
- chipgraph/core/runtime/roles/data/triage.md +34 -0
- chipgraph/core/runtime/roles/policy.py +299 -0
- chipgraph/core/runtime/roles/registry.py +52 -0
- chipgraph/core/runtime/roles/review.py +275 -0
- chipgraph/core/runtime/roles/schema.py +82 -0
- chipgraph/core/runtime/roles/skills.py +134 -0
- chipgraph/core/runtime/roles/spec.py +232 -0
- chipgraph/core/state/__init__.py +1 -0
- chipgraph/core/state/artifacts.py +156 -0
- chipgraph/core/state/backend.py +117 -0
- chipgraph/core/state/findings.py +151 -0
- chipgraph/core/state/handoff.py +411 -0
- chipgraph/core/state/idempotency.py +59 -0
- chipgraph/core/state/journal.py +238 -0
- chipgraph/core/state/layout.py +82 -0
- chipgraph/core/state/lock.py +195 -0
- chipgraph/core/state/trace.py +225 -0
- chipgraph/learn/__init__.py +96 -0
- chipgraph/learn/draft.py +187 -0
- chipgraph/learn/infer.py +580 -0
- chipgraph/learn/models.py +145 -0
- chipgraph/learn/try_run.py +228 -0
- chipgraph/mcp/__init__.py +12 -0
- chipgraph/mcp/model_tools.py +167 -0
- chipgraph/mcp/server.py +787 -0
- chipgraph/orgs/qnsc/naming-v1.yml +113 -0
- chipgraph/orgs/qnsc/profile.yml +5 -0
- chipgraph/packs/__init__.py +8 -0
- chipgraph/packs/assist/__init__.py +16 -0
- chipgraph/packs/assist/ask/__init__.py +58 -0
- chipgraph/packs/assist/ask/_db.py +57 -0
- chipgraph/packs/assist/ask/_project.py +230 -0
- chipgraph/packs/assist/ask/answer.py +266 -0
- chipgraph/packs/assist/ask/check.py +182 -0
- chipgraph/packs/assist/ask/contract.py +115 -0
- chipgraph/packs/assist/ask/documents.py +157 -0
- chipgraph/packs/assist/ask/fts.py +80 -0
- chipgraph/packs/assist/ask/retrieve.py +331 -0
- chipgraph/packs/assist/audit/__init__.py +383 -0
- chipgraph/packs/assist/pack.yml +13 -0
- chipgraph/packs/assist/triage/__init__.py +64 -0
- chipgraph/packs/assist/triage/contract.py +94 -0
- chipgraph/packs/assist/triage/parse.py +371 -0
- chipgraph/packs/assist/triage/question.py +384 -0
- chipgraph/packs/assist/triage/report.py +160 -0
- chipgraph/packs/assist/triage/rules.py +447 -0
- chipgraph/packs/assist/triage/run.py +224 -0
- chipgraph/packs/digital_rtl/__init__.py +19 -0
- chipgraph/packs/digital_rtl/layout.py +144 -0
- chipgraph/packs/digital_rtl/pack.yml +25 -0
- chipgraph/packs/digital_rtl/plan/__init__.py +34 -0
- chipgraph/packs/digital_rtl/plan/__main__.py +16 -0
- chipgraph/packs/digital_rtl/plan/context.py +82 -0
- chipgraph/packs/digital_rtl/plan/expand.py +94 -0
- chipgraph/packs/digital_rtl/plan/model.py +150 -0
- chipgraph/packs/digital_rtl/plan/resolver.py +400 -0
- chipgraph/packs/digital_rtl/plan/show.py +176 -0
- chipgraph/packs/digital_rtl/pr/__init__.py +11 -0
- chipgraph/packs/digital_rtl/pr/body.py +165 -0
- chipgraph/packs/digital_rtl/pr/gate.py +110 -0
- chipgraph/packs/digital_rtl/pr/open.py +397 -0
- chipgraph/packs/digital_rtl/rtl/__init__.py +9 -0
- chipgraph/packs/digital_rtl/rtl/context.py +272 -0
- chipgraph/packs/digital_rtl/rules/open_pr.yml +30 -0
- chipgraph/packs/digital_rtl/rules/plan.yml +28 -0
- chipgraph/packs/digital_rtl/rules/plan_expand.yml +29 -0
- chipgraph/packs/digital_rtl/rules/pr_gate.yml +27 -0
- chipgraph/packs/digital_rtl/rules/review.yml +31 -0
- chipgraph/packs/digital_rtl/rules/rtl_module.yml +53 -0
- chipgraph/packs/digital_rtl/skills/lang-sv-rtl.md +58 -0
- chipgraph/packs/digital_rtl/skills/org-naming.md +29 -0
- chipgraph/packs/digital_rtl/skills/plan-modules.md +63 -0
- chipgraph/packs/digital_rtl/skills/review-diff.md +41 -0
- chipgraph/packs/digital_rtl/targets/plan.yml +11 -0
- chipgraph/packs/digital_rtl/targets/rtl.yml +20 -0
- chipgraph/packs/digital_rtl/wrapper/__init__.py +24 -0
- chipgraph/packs/digital_rtl/wrapper/common.py +171 -0
- chipgraph/packs/digital_rtl/wrapper/context.py +222 -0
- chipgraph/packs/digital_rtl/wrapper/emacs.py +626 -0
- chipgraph/packs/digital_rtl/wrapper/expansion.py +304 -0
- chipgraph/packs/digital_rtl/wrapper/lisp.py +504 -0
- chipgraph/packs/digital_rtl/wrapper/resolver.py +60 -0
- chipgraph/packs/digital_rtl/wrapper/rules/wrapper.yml +41 -0
- chipgraph/packs/digital_rtl/wrapper/rules/wrapper_gen.yml +35 -0
- chipgraph/packs/digital_rtl/wrapper/skills/wrapper-auto.md +120 -0
- chipgraph/packs/dv/__init__.py +15 -0
- chipgraph/packs/dv/declaration.py +392 -0
- chipgraph/packs/dv/interface.py +596 -0
- chipgraph/packs/dv/pack.yml +14 -0
- chipgraph/packs/dv/rules/tb_module.yml +42 -0
- chipgraph/packs/dv/skills/dv/cocotb.md +72 -0
- chipgraph/packs/spec_core/__init__.py +9 -0
- chipgraph/packs/spec_core/extract/__init__.py +12 -0
- chipgraph/packs/spec_core/extract/_markdown.py +371 -0
- chipgraph/packs/spec_core/extract/_text.py +116 -0
- chipgraph/packs/spec_core/extract/mas.py +975 -0
- chipgraph/packs/spec_core/gen/__init__.py +11 -0
- chipgraph/packs/spec_core/gen/agents_md/__init__.py +148 -0
- chipgraph/packs/spec_core/gen/agents_md/_context.py +239 -0
- chipgraph/packs/spec_core/gen/agents_md/_markers.py +131 -0
- chipgraph/packs/spec_core/gen/agents_md/agents_md.md.j2 +178 -0
- chipgraph/packs/spec_core/gen/diagram/__init__.py +110 -0
- chipgraph/packs/spec_core/gen/diagram/__main__.py +44 -0
- chipgraph/packs/spec_core/gen/diagram/_diagrams.py +403 -0
- chipgraph/packs/spec_core/gen/diagram/_scene.py +163 -0
- chipgraph/packs/spec_core/pack.yml +6 -0
- chipgraph/py.typed +0 -0
- chipgraph-0.1.0.dist-info/METADATA +53 -0
- chipgraph-0.1.0.dist-info/RECORD +252 -0
- chipgraph-0.1.0.dist-info/WHEEL +4 -0
- chipgraph-0.1.0.dist-info/entry_points.txt +61 -0
- chipgraph-0.1.0.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""The context of a task whose role must not see some artifacts (DESIGN.md 5.1, 5.3 F1).
|
|
2
|
+
|
|
3
|
+
`get_context` of runtime `claude-code` uses one of these for a task of a role with
|
|
4
|
+
`read_policy.deny_kinds` (`guarded_context` picks it): `GuardedContext` for a role that
|
|
5
|
+
must not see the RTL (the testbench Author), `RtlAuthorContext` for one that must not see
|
|
6
|
+
the testbench (the RTL Author). Both give the model inputs, the extra context sections
|
|
7
|
+
and the block's spec documents; the read policy itself (what is refused, what is
|
|
8
|
+
filtered) is the same engine for both (`chipgraph.core.runtime.roles.policy`).
|
|
9
|
+
|
|
10
|
+
**Not the RTL** (`GuardedContext`): its Design Model inputs are not the general model
|
|
11
|
+
slices, which name modules, RTL ports and RTL files, but
|
|
12
|
+
|
|
13
|
+
- ``block/<b>``: the block's spec side (`chipgraph.packs.dv.interface.spec_slice`):
|
|
14
|
+
requirements with their ids, registers and fields, interrupts, memory regions, clock
|
|
15
|
+
and reset;
|
|
16
|
+
- ``interface/<name>`` (a module, or a block for its top module): the interface from
|
|
17
|
+
`project_interface` (spec ports, else the model's RTL ports, else the module's
|
|
18
|
+
declaration only), also given as the context's `interface` section;
|
|
19
|
+
- anything else: a note, no content.
|
|
20
|
+
|
|
21
|
+
The context also gets a `requirements` section (every requirement of the task's block,
|
|
22
|
+
with its id), and the block's spec documents (the profile layout's `spec` paths) as
|
|
23
|
+
inputs when the rule does not list them. Nothing else derived from RTL goes in: no RTL
|
|
24
|
+
file, body text, line number or path.
|
|
25
|
+
|
|
26
|
+
**Not the testbench** (`RtlAuthorContext`, M2-04): the model input ``block/<b>`` is the
|
|
27
|
+
block's spec side with the requirements cut to the module's, ``interface/<module>`` points
|
|
28
|
+
to the `rtl` section, and the `rtl` section holds the module's approved plan entry, its
|
|
29
|
+
requirements, interface and dependencies, the naming rules as text and the style
|
|
30
|
+
exemplars (`chipgraph.packs.digital_rtl.rtl.context`). An exemplar the role must not read
|
|
31
|
+
is refused there. No other project file's text. A wrapper's task (a `wrapper` param,
|
|
32
|
+
M2-12) gets `rtl.wrapper` instead: the IP's port declaration, the wrapper's ports and the
|
|
33
|
+
naming rules (`chipgraph.packs.digital_rtl.wrapper.context`), never the IP's body.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
import json
|
|
39
|
+
from collections.abc import Callable, Sequence
|
|
40
|
+
from typing import Any
|
|
41
|
+
|
|
42
|
+
from chipgraph.app.context import AppContext
|
|
43
|
+
from chipgraph.core.contracts import RuleInstance, RuleSpec
|
|
44
|
+
from chipgraph.core.model import DesignModel, ModelStore, ModelStoreError, default_model_db_path
|
|
45
|
+
from chipgraph.core.runtime.roles import RoleSpec
|
|
46
|
+
from chipgraph.packs.dv.interface import (
|
|
47
|
+
Interface,
|
|
48
|
+
block_requirements,
|
|
49
|
+
project_interface,
|
|
50
|
+
spec_slice,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
TB_STATIC = "tb_static"
|
|
54
|
+
"""The adapter id whose args (`top`, `files`, `filelist`) say where a module's declaration
|
|
55
|
+
is, so the context and the `tb_static` check see the same interface."""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def spec_documents(ctx: AppContext, block: str | None) -> list[str]:
|
|
59
|
+
"""The block's spec documents that exist: the profile layout's `spec` paths."""
|
|
60
|
+
if block is None:
|
|
61
|
+
return []
|
|
62
|
+
value = ctx.require_profile().for_block(block).layout.get("spec")
|
|
63
|
+
templates = [value] if isinstance(value, str) else list(value or ())
|
|
64
|
+
found: list[str] = []
|
|
65
|
+
for template in templates:
|
|
66
|
+
rel = template.replace("{block}", block).replace("{BLOCK}", block.upper())
|
|
67
|
+
if "{" in rel:
|
|
68
|
+
continue
|
|
69
|
+
paths = sorted(ctx.root.glob(rel)) if set("*?[") & set(rel) else [ctx.root / rel]
|
|
70
|
+
for path in paths:
|
|
71
|
+
if path.is_file():
|
|
72
|
+
name = path.relative_to(ctx.root).as_posix()
|
|
73
|
+
if name not in found:
|
|
74
|
+
found.append(name)
|
|
75
|
+
return found
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _load_model(ctx: AppContext) -> DesignModel | None:
|
|
79
|
+
db = default_model_db_path(ctx.layout.root)
|
|
80
|
+
if not db.is_file():
|
|
81
|
+
return None
|
|
82
|
+
try:
|
|
83
|
+
return ModelStore(db).read()
|
|
84
|
+
except (ModelStoreError, OSError, ValueError):
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class GuardedContext:
|
|
89
|
+
"""The model inputs and extra sections of one task that must not see RTL."""
|
|
90
|
+
|
|
91
|
+
instructions = (
|
|
92
|
+
" The ports you may use are in `interface` (every port names its `source`), "
|
|
93
|
+
"the block's requirements in `requirements`."
|
|
94
|
+
)
|
|
95
|
+
"""What `get_context` adds to the task's instructions."""
|
|
96
|
+
|
|
97
|
+
def covers(self, path: str) -> str | None:
|
|
98
|
+
"""The context section that already holds file input `path`, if any (none here)."""
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
def __init__(self, ctx: AppContext, instance: RuleInstance) -> None:
|
|
102
|
+
self.ctx = ctx
|
|
103
|
+
self.instance = instance
|
|
104
|
+
self.block = instance.params.get("block")
|
|
105
|
+
self._model: DesignModel | None = None
|
|
106
|
+
self._loaded = False
|
|
107
|
+
self.interface: Interface | None = None
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def model(self) -> DesignModel | None:
|
|
111
|
+
"""The ingested Design Model, or None when there is none yet."""
|
|
112
|
+
if not self._loaded:
|
|
113
|
+
self._loaded = True
|
|
114
|
+
self._model = _load_model(self.ctx)
|
|
115
|
+
return self._model
|
|
116
|
+
|
|
117
|
+
def _profile_parts(self, block: str | None) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
118
|
+
resolved = self.ctx.require_profile()
|
|
119
|
+
profile = resolved.for_block(block) if block is not None else resolved.profile
|
|
120
|
+
cfg = profile.adapters.get(TB_STATIC)
|
|
121
|
+
args = cfg.model_dump() if cfg is not None else {}
|
|
122
|
+
return args, dict(profile.layout)
|
|
123
|
+
|
|
124
|
+
def _interface(self, name: str) -> Interface:
|
|
125
|
+
blocks = self.ctx.require_profile().profile.blocks
|
|
126
|
+
params = dict(self.instance.params)
|
|
127
|
+
block: str | None
|
|
128
|
+
if name in blocks or name == self.block:
|
|
129
|
+
block = name
|
|
130
|
+
else:
|
|
131
|
+
block = self.block
|
|
132
|
+
params["module"] = name
|
|
133
|
+
args, layout = self._profile_parts(block)
|
|
134
|
+
return project_interface(
|
|
135
|
+
self.ctx.root, model=self.model, block=block, params=params, args=args, layout=layout
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
def spec_documents(self) -> list[str]:
|
|
139
|
+
"""The block's spec documents that exist: the profile layout's `spec` paths."""
|
|
140
|
+
return spec_documents(self.ctx, self.block)
|
|
141
|
+
|
|
142
|
+
def model_input(self, key: str) -> dict[str, Any]:
|
|
143
|
+
"""The context entry of the model input `key`."""
|
|
144
|
+
entry: dict[str, Any] = {"model_key": key}
|
|
145
|
+
kind, _, name = key.partition("/")
|
|
146
|
+
if kind == "interface" and name:
|
|
147
|
+
self.interface = self._interface(name)
|
|
148
|
+
entry["section"] = "interface"
|
|
149
|
+
entry["note"] = "see the context's `interface` section"
|
|
150
|
+
return entry
|
|
151
|
+
if kind == "block" and name:
|
|
152
|
+
model = self.model
|
|
153
|
+
if model is None:
|
|
154
|
+
entry["note"] = "not available from the Design Model (run `chipgraph ingest` first)"
|
|
155
|
+
return entry
|
|
156
|
+
entry["content"] = json.dumps(spec_slice(model, name), indent=1, sort_keys=True)
|
|
157
|
+
return entry
|
|
158
|
+
entry["note"] = f"model input {key!r} is not available to this role"
|
|
159
|
+
return entry
|
|
160
|
+
|
|
161
|
+
def sections(self) -> dict[str, Any]:
|
|
162
|
+
"""The extra context sections: `interface` (when an input asked for it) and
|
|
163
|
+
`requirements` (the block's, with ids)."""
|
|
164
|
+
out: dict[str, Any] = {}
|
|
165
|
+
if self.interface is not None:
|
|
166
|
+
out["interface"] = self.interface.view()
|
|
167
|
+
model = self.model
|
|
168
|
+
if model is not None and self.block is not None:
|
|
169
|
+
out["requirements"] = block_requirements(model, self.block)
|
|
170
|
+
return out
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class RtlAuthorContext:
|
|
174
|
+
"""The model inputs and extra sections of one task that must not see a testbench."""
|
|
175
|
+
|
|
176
|
+
instructions = (
|
|
177
|
+
" Everything about the module is in `rtl`: its approved plan entry (`rtl.module`), "
|
|
178
|
+
"its requirements with ids, its ports (`rtl.interface`, every port names its "
|
|
179
|
+
"`source`), the modules it connects to, the naming rules (`rtl.naming.text`) and "
|
|
180
|
+
"the style exemplars to imitate (`rtl.style`). The engine formats your file before "
|
|
181
|
+
"the other checks run."
|
|
182
|
+
)
|
|
183
|
+
"""What `get_context` adds to the task's instructions."""
|
|
184
|
+
|
|
185
|
+
def __init__(
|
|
186
|
+
self,
|
|
187
|
+
ctx: AppContext,
|
|
188
|
+
instance: RuleInstance,
|
|
189
|
+
rules: Sequence[RuleSpec],
|
|
190
|
+
is_denied: Callable[[str], bool],
|
|
191
|
+
) -> None:
|
|
192
|
+
self.ctx = ctx
|
|
193
|
+
self.instance = instance
|
|
194
|
+
self.rules = list(rules)
|
|
195
|
+
self.is_denied = is_denied
|
|
196
|
+
self.block = instance.params.get("block")
|
|
197
|
+
self.module = instance.params.get("module")
|
|
198
|
+
self.wrapper = instance.params.get("wrapper")
|
|
199
|
+
self.model = _load_model(ctx)
|
|
200
|
+
self._section: dict[str, Any] | None = None
|
|
201
|
+
if self.wrapper is not None: # a wrapper's source (M2-12): `rtl.wrapper`
|
|
202
|
+
from chipgraph.packs.digital_rtl.wrapper.context import INSTRUCTIONS
|
|
203
|
+
|
|
204
|
+
self.instructions = INSTRUCTIONS
|
|
205
|
+
|
|
206
|
+
def section(self) -> dict[str, Any]:
|
|
207
|
+
"""The `rtl` section (built once)."""
|
|
208
|
+
if self._section is None:
|
|
209
|
+
from chipgraph.packs.digital_rtl.rtl.context import rtl_author_context
|
|
210
|
+
|
|
211
|
+
if self.block is None:
|
|
212
|
+
self._section = {"note": "this task has no block param"}
|
|
213
|
+
elif self.wrapper is not None:
|
|
214
|
+
from chipgraph.packs.digital_rtl.wrapper.context import wrapper_author_context
|
|
215
|
+
|
|
216
|
+
self._section = wrapper_author_context(
|
|
217
|
+
self.ctx.root,
|
|
218
|
+
self.ctx.require_profile(),
|
|
219
|
+
self.rules,
|
|
220
|
+
params=dict(self.instance.params),
|
|
221
|
+
outputs=[r.path for r in self.instance.outputs if r.path is not None],
|
|
222
|
+
model=self.model,
|
|
223
|
+
is_denied=self.is_denied,
|
|
224
|
+
)
|
|
225
|
+
else:
|
|
226
|
+
self._section = rtl_author_context(
|
|
227
|
+
self.ctx.root,
|
|
228
|
+
self.ctx.require_profile(),
|
|
229
|
+
self.rules,
|
|
230
|
+
block=self.block,
|
|
231
|
+
module=self.module,
|
|
232
|
+
model=self.model,
|
|
233
|
+
is_denied=self.is_denied,
|
|
234
|
+
)
|
|
235
|
+
return self._section
|
|
236
|
+
|
|
237
|
+
def spec_documents(self) -> list[str]:
|
|
238
|
+
"""The block's spec documents that exist: the profile layout's `spec` paths."""
|
|
239
|
+
return spec_documents(self.ctx, self.block)
|
|
240
|
+
|
|
241
|
+
def covers(self, path: str) -> str | None:
|
|
242
|
+
"""`rtl.style` / `rtl.naming` for a style input (an exemplar or the naming rules
|
|
243
|
+
file, which the resolver adds as inputs so an edit makes the module stale): the
|
|
244
|
+
section shows it, capped and labelled, so its text is not given twice."""
|
|
245
|
+
section = self.section()
|
|
246
|
+
style = section.get("style")
|
|
247
|
+
exemplars = style.get("exemplars", []) if isinstance(style, dict) else []
|
|
248
|
+
if any(isinstance(e, dict) and e.get("path") == path for e in exemplars):
|
|
249
|
+
return "rtl.style"
|
|
250
|
+
if self.block is not None:
|
|
251
|
+
from chipgraph.packs.digital_rtl.plan.resolver import style_inputs
|
|
252
|
+
|
|
253
|
+
if path in style_inputs(self.ctx, self.rules, self.block):
|
|
254
|
+
return "rtl.naming"
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
def model_input(self, key: str) -> dict[str, Any]:
|
|
258
|
+
"""The context entry of the model input `key`."""
|
|
259
|
+
from chipgraph.packs.digital_rtl.rtl.context import spec_side
|
|
260
|
+
|
|
261
|
+
entry: dict[str, Any] = {"model_key": key}
|
|
262
|
+
kind, _, name = key.partition("/")
|
|
263
|
+
if kind == "interface" and name and self.wrapper is not None:
|
|
264
|
+
entry["section"] = "rtl.wrapper.interface"
|
|
265
|
+
entry["note"] = "see the context's `rtl.wrapper.interface` and `rtl.wrapper.vendor`"
|
|
266
|
+
return entry
|
|
267
|
+
if kind == "interface" and name:
|
|
268
|
+
entry["section"] = "rtl.interface"
|
|
269
|
+
entry["note"] = "see the context's `rtl.interface` and `rtl.dependencies`"
|
|
270
|
+
return entry
|
|
271
|
+
if kind == "block" and name:
|
|
272
|
+
if self.model is None:
|
|
273
|
+
entry["note"] = "not available from the Design Model (run `chipgraph ingest` first)"
|
|
274
|
+
return entry
|
|
275
|
+
module = self.section().get("module")
|
|
276
|
+
reqs = list(module.get("reqs", ())) if isinstance(module, dict) else None
|
|
277
|
+
side = spec_side(self.model, name, reqs)
|
|
278
|
+
entry["content"] = json.dumps(side, indent=1, sort_keys=True)
|
|
279
|
+
return entry
|
|
280
|
+
entry["note"] = f"model input {key!r} is not available to this role"
|
|
281
|
+
return entry
|
|
282
|
+
|
|
283
|
+
def sections(self) -> dict[str, Any]:
|
|
284
|
+
"""The extra context section: `rtl`."""
|
|
285
|
+
return {"rtl": self.section()}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def guarded_context(
|
|
289
|
+
ctx: AppContext,
|
|
290
|
+
role: RoleSpec | None,
|
|
291
|
+
instance: RuleInstance,
|
|
292
|
+
rules: Sequence[RuleSpec],
|
|
293
|
+
is_denied: Callable[[str], bool],
|
|
294
|
+
) -> GuardedContext | RtlAuthorContext | None:
|
|
295
|
+
"""The guarded context of a task whose role must not see some kinds, else None.
|
|
296
|
+
|
|
297
|
+
A role that must not see `rtl` gets `GuardedContext`; one that must not see `tb`
|
|
298
|
+
(and may see RTL) gets `RtlAuthorContext`.
|
|
299
|
+
"""
|
|
300
|
+
if role is None or role.read_policy.mode != "deny" or not role.read_policy.deny_kinds:
|
|
301
|
+
return None
|
|
302
|
+
kinds = role.read_policy.deny_kinds
|
|
303
|
+
if "rtl" in kinds:
|
|
304
|
+
return GuardedContext(ctx, instance)
|
|
305
|
+
if "tb" in kinds:
|
|
306
|
+
return RtlAuthorContext(ctx, instance, rules, is_denied)
|
|
307
|
+
return None
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
__all__ = ["TB_STATIC", "GuardedContext", "RtlAuthorContext", "guarded_context", "spec_documents"]
|