Skip to content

Commit a3bac76

Browse files
committed
feat(config): add [chipflow.backend] passthrough to submission manifest
Free-form table copied verbatim into `manifest["backend"]` so the backend can grow its own knobs (build_mode, etc.) without a chipflow-lib release. Omitted from the manifest when empty.
1 parent a11fb53 commit a3bac76

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

chipflow/config/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ class ChipFlowConfig(BaseModel):
113113
software: SoftwareConfig = SoftwareConfig()
114114
clock_domains: Optional[List[str]] = None
115115
test: Optional[TestConfig] = None
116+
# Free-form parameters copied verbatim into the submission manifest
117+
# under `manifest["backend"]`. The backend defines and validates the
118+
# schema; chipflow-lib treats this as an opaque pass-through.
119+
backend: Dict[str, Any] = {}
116120

117121
class Config(BaseModel):
118122
"""Root configuration model for chipflow.toml."""

chipflow/platform/silicon_step.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def _build_bundle_zip(
3939
process: str,
4040
package: str,
4141
macros: dict | None = None,
42+
backend: dict | None = None,
4243
) -> bytes:
4344
"""Pack the submission into a single zip with a manifest.
4445
@@ -78,6 +79,8 @@ def _build_bundle_zip(
7879
"design_file": design_arc,
7980
"pins_lock_file": pins_lock_arc,
8081
}
82+
if backend:
83+
manifest["backend"] = backend
8184

8285
file_entries: list[tuple[str, Path]] = [] # (archive_path, real_path)
8386
if macros:
@@ -268,7 +271,8 @@ def submit(self, rtlil_path, args):
268271
self.config.chipflow.project_name,
269272
self.config.chipflow.silicon.process.value,
270273
self.config.chipflow.silicon.package,
271-
self.platform._macros)
274+
self.platform._macros,
275+
self.config.chipflow.backend or None)
272276

273277
if args.dry_run:
274278
sp.succeed(f"✅ Design `{data['projectId']}:{data['name']}` ready for submission to ChipFlow cloud!")

tests/test_silicon_submit.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,37 @@ def test_uses_real_rtlil_filename(self):
218218
manifest = json.loads(zf.read("manifest.json"))
219219
self.assertEqual(manifest["design_file"], "weird_name.rtlil")
220220

221+
def test_backend_section_passthrough(self):
222+
"""Contents of [chipflow.backend] land verbatim under manifest.backend."""
223+
with tempfile.TemporaryDirectory() as td:
224+
rtlil_path = Path(td) / "top.il"
225+
rtlil_path.write_text("x")
226+
backend = {"build_mode": "synth_only", "knob": 42, "nested": {"a": 1}}
227+
blob = _build_bundle_zip(
228+
rtlil_path, "{}", "p", "sky130", "cf20",
229+
backend=backend,
230+
)
231+
with zipfile.ZipFile(io.BytesIO(blob)) as zf:
232+
manifest = json.loads(zf.read("manifest.json"))
233+
self.assertEqual(manifest["backend"], backend)
234+
235+
def test_backend_omitted_when_empty(self):
236+
"""Empty/None backend → no `backend` key in manifest (clean default)."""
237+
with tempfile.TemporaryDirectory() as td:
238+
rtlil_path = Path(td) / "top.il"
239+
rtlil_path.write_text("x")
240+
blob = _build_bundle_zip(rtlil_path, "{}", "p", "sky130", "cf20")
241+
with zipfile.ZipFile(io.BytesIO(blob)) as zf:
242+
manifest = json.loads(zf.read("manifest.json"))
243+
self.assertNotIn("backend", manifest)
244+
245+
blob = _build_bundle_zip(
246+
rtlil_path, "{}", "p", "sky130", "cf20", backend={},
247+
)
248+
with zipfile.ZipFile(io.BytesIO(blob)) as zf:
249+
manifest = json.loads(zf.read("manifest.json"))
250+
self.assertNotIn("backend", manifest)
251+
221252

222253
class TestSiliconSubmitBundlePost(unittest.TestCase):
223254
"""The submit() path posts a single 'bundle' multipart part."""

0 commit comments

Comments
 (0)