circuitsilk 0.2.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.
- circuitsilk-0.2.0.dist-info/METADATA +475 -0
- circuitsilk-0.2.0.dist-info/RECORD +350 -0
- circuitsilk-0.2.0.dist-info/WHEEL +5 -0
- circuitsilk-0.2.0.dist-info/licenses/LICENSE +21 -0
- circuitsilk-0.2.0.dist-info/top_level.txt +1 -0
- silk/__init__.py +206 -0
- silk/_json_codec.py +111 -0
- silk/circuit/__init__.py +43 -0
- silk/circuit/_behavioral_identity.py +146 -0
- silk/circuit/_module_base.py +570 -0
- silk/circuit/_module_protocol.py +115 -0
- silk/circuit/_results_json.py +467 -0
- silk/circuit/_spec_report_json.py +375 -0
- silk/circuit/bus_spec.py +154 -0
- silk/circuit/circuit_elements.py +1175 -0
- silk/circuit/composition.py +1124 -0
- silk/circuit/data/port-roles.default.yaml +18 -0
- silk/circuit/data/region-thresholds.default.yaml +22 -0
- silk/circuit/declared_indices.py +32 -0
- silk/circuit/device_view.py +139 -0
- silk/circuit/emitted_names.py +310 -0
- silk/circuit/ground_port.py +157 -0
- silk/circuit/interface_check.py +317 -0
- silk/circuit/junction_check.py +70 -0
- silk/circuit/metric_handle.py +207 -0
- silk/circuit/module_placement.py +337 -0
- silk/circuit/module_test.py +7108 -0
- silk/circuit/modules.py +385 -0
- silk/circuit/modules_db.py +785 -0
- silk/circuit/modules_faults.py +163 -0
- silk/circuit/modules_netlist.py +943 -0
- silk/circuit/modules_results.py +1905 -0
- silk/circuit/modules_sim.py +1215 -0
- silk/circuit/modules_spec.py +278 -0
- silk/circuit/modules_structure.py +1979 -0
- silk/circuit/modules_testbench.py +960 -0
- silk/circuit/monte_carlo.py +1050 -0
- silk/circuit/monte_carlo_draws.py +428 -0
- silk/circuit/monte_carlo_report.py +353 -0
- silk/circuit/net.py +313 -0
- silk/circuit/node_paths.py +303 -0
- silk/circuit/object_holders.py +154 -0
- silk/circuit/op_table.py +570 -0
- silk/circuit/placement_reference.py +465 -0
- silk/circuit/port_binding.py +41 -0
- silk/circuit/port_roles.py +366 -0
- silk/circuit/ports.py +447 -0
- silk/circuit/region_thresholds.py +137 -0
- silk/circuit/report.py +3270 -0
- silk/circuit/report_diff.py +1128 -0
- silk/circuit/rolecheck.py +19 -0
- silk/circuit/spec_report.py +1224 -0
- silk/circuit/spice_netlister.py +1688 -0
- silk/circuit/sweep_sources.py +64 -0
- silk/circuit/test_execution.py +189 -0
- silk/circuit/test_failure.py +243 -0
- silk/circuit/test_placement.py +702 -0
- silk/circuit/variable.py +741 -0
- silk/circuit/view_nodes.py +280 -0
- silk/circuit/voltage_domain.py +153 -0
- silk/circuit/wiring_consistency.py +88 -0
- silk/circuit/xyce_ground.py +117 -0
- silk/circuit/xyce_netlister.py +390 -0
- silk/codegen/__init__.py +18 -0
- silk/codegen/generator.py +2900 -0
- silk/codegen/source_names.py +61 -0
- silk/codegen/testbench_generator.py +1736 -0
- silk/constraints/__init__.py +63 -0
- silk/constraints/_module_patch.py +72 -0
- silk/constraints/_netlist_view.py +43 -0
- silk/constraints/checkers.py +120 -0
- silk/constraints/envelope.py +83 -0
- silk/constraints/serialization.py +260 -0
- silk/constraints/types.py +304 -0
- silk/db/__init__.py +86 -0
- silk/db/_attempts.py +87 -0
- silk/db/_condition_columns.py +152 -0
- silk/db/_deck_check.py +263 -0
- silk/db/_source_identity.py +138 -0
- silk/db/circuit_db.py +6226 -0
- silk/db/circuit_import.py +1020 -0
- silk/db/context.py +354 -0
- silk/db/identity.py +800 -0
- silk/db/migration.py +1183 -0
- silk/db/models.py +675 -0
- silk/db/schema.py +814 -0
- silk/db/structure_tracker.py +1196 -0
- silk/db/tracking.py +2585 -0
- silk/doctor.py +501 -0
- silk/elements/__init__.py +31 -0
- silk/elements/_catalog.py +32 -0
- silk/elements/analog_devices.yaml +83 -0
- silk/elements/base.py +484 -0
- silk/elements/factory.py +649 -0
- silk/elements/library.py +82 -0
- silk/elements/passives.py +284 -0
- silk/elements/schema.py +448 -0
- silk/examples/__init__.py +76 -0
- silk/examples/abo_th_example.py +546 -0
- silk/examples/amplifier_variants_example.py +155 -0
- silk/examples/bandgap_example.py +439 -0
- silk/examples/behavioral_example.py +167 -0
- silk/examples/bus_ports_example.py +243 -0
- silk/examples/charge_pump_example.py +253 -0
- silk/examples/circuit_report_example.py +105 -0
- silk/examples/circuit_tracking_example.py +258 -0
- silk/examples/cml_cells.py +852 -0
- silk/examples/cml_ffe_eye.py +110 -0
- silk/examples/cmos_ffe_eye.py +157 -0
- silk/examples/compare_outputs.py +53 -0
- silk/examples/composition_graph_demo.py +53 -0
- silk/examples/constraints_5t_ota.py +205 -0
- silk/examples/constraints_current_mirror.py +129 -0
- silk/examples/constraints_diff_pair.py +120 -0
- silk/examples/constraints_external_load.py +153 -0
- silk/examples/current_mirror_example.py +199 -0
- silk/examples/design_loop_walkthrough.py +773 -0
- silk/examples/design_loop_walkthrough_gf180mcu.py +154 -0
- silk/examples/design_loop_walkthrough_sg13g2.py +364 -0
- silk/examples/diff_pair_construction_example.py +82 -0
- silk/examples/differential_th_example.py +162 -0
- silk/examples/eye_centering.py +69 -0
- silk/examples/factory_api_example.py +118 -0
- silk/examples/fault_injection_example.py +135 -0
- silk/examples/flash_adc_example.py +1371 -0
- silk/examples/folded_cascode.py +232 -0
- silk/examples/gm_id_lookup.py +316 -0
- silk/examples/hierarchical_example.py +191 -0
- silk/examples/layout_intelligence_example.py +425 -0
- silk/examples/ldo_calibrate.py +188 -0
- silk/examples/ldo_design.py +174 -0
- silk/examples/ldo_regulator_example.py +615 -0
- silk/examples/lint_coverage_example.py +307 -0
- silk/examples/mc_diff_pair_offset.py +106 -0
- silk/examples/metrics/__init__.py +13 -0
- silk/examples/metrics/comparator_and_sampler.py +506 -0
- silk/examples/metrics/cs_amp_ac_noise.py +321 -0
- silk/examples/metrics/cs_amp_distortion.py +211 -0
- silk/examples/metrics/cs_amp_power_sweep.py +256 -0
- silk/examples/metrics/cs_amp_two_tone.py +213 -0
- silk/examples/metrics/diff_pair_rejection.py +323 -0
- silk/examples/metrics/flash_adc_codes.py +307 -0
- silk/examples/metrics/inverter_timing.py +219 -0
- silk/examples/metrics/prbs_eye.py +415 -0
- silk/examples/metrics/ring_osc_jitter.py +349 -0
- silk/examples/metrics/rlc_filter_ac.py +159 -0
- silk/examples/metrics/rlc_step.py +183 -0
- silk/examples/net_current_persistence_example.py +356 -0
- silk/examples/net_object_example.py +162 -0
- silk/examples/ota_5t_guide.py +299 -0
- silk/examples/output_modes_example.py +182 -0
- silk/examples/parameter_sweep_example.py +212 -0
- silk/examples/pfd_example.py +435 -0
- silk/examples/pll_calibrate.py +106 -0
- silk/examples/pll_example.py +443 -0
- silk/examples/pll_spec_tree_example.py +284 -0
- silk/examples/pll_spice_example.py +275 -0
- silk/examples/pll_twin_vs_spice.py +105 -0
- silk/examples/port_role_example.py +167 -0
- silk/examples/port_role_inference_example.py +129 -0
- silk/examples/prbs_generator_example.py +573 -0
- silk/examples/pwl_example.py +202 -0
- silk/examples/ring_calibrate.py +153 -0
- silk/examples/ring_oscillator_example.py +446 -0
- silk/examples/ring_oscillator_stage_sweep.py +112 -0
- silk/examples/sar_adc_example.py +288 -0
- silk/examples/sar_adc_spice.py +1212 -0
- silk/examples/sar_calibrate.py +62 -0
- silk/examples/sar_resolution_sweep.py +353 -0
- silk/examples/serdes_tx_driver_example.py +348 -0
- silk/examples/serdes_tx_example.py +978 -0
- silk/examples/serializer_example.py +552 -0
- silk/examples/source_examples.py +288 -0
- silk/examples/source_follower_calibrate.py +293 -0
- silk/examples/source_follower_example.py +298 -0
- silk/examples/source_follower_optimize.py +55 -0
- silk/examples/stdcells.py +982 -0
- silk/examples/strongarm_tb.py +874 -0
- silk/examples/supply_regulated_vco_example.py +286 -0
- silk/examples/testbench_codegen_example.py +117 -0
- silk/examples/two_stage_miller_ota_example.py +308 -0
- silk/exceptions.py +428 -0
- silk/faults/__init__.py +33 -0
- silk/faults/application.py +318 -0
- silk/faults/campaign.py +763 -0
- silk/faults/evaluation.py +299 -0
- silk/faults/pdk_metadata.py +125 -0
- silk/faults/report.py +370 -0
- silk/faults/runner.py +148 -0
- silk/faults/set.py +287 -0
- silk/faults/sugar.py +386 -0
- silk/faults/types.py +206 -0
- silk/layout/__init__.py +35 -0
- silk/layout/_types.py +39 -0
- silk/layout/area_model.py +248 -0
- silk/layout/estimator.py +610 -0
- silk/layout/matching.py +273 -0
- silk/layout/parasitics.py +242 -0
- silk/layout/routing_model.py +152 -0
- silk/layout/wirelength_model.py +66 -0
- silk/lint/__init__.py +84 -0
- silk/lint/exclusions.py +117 -0
- silk/lint/help.py +66 -0
- silk/lint/locations.py +152 -0
- silk/lint/registry.py +409 -0
- silk/lint/reports/__init__.py +12 -0
- silk/lint/reports/coverage_report.py +471 -0
- silk/lint/reports/lint_report.py +595 -0
- silk/lint/reports/metadata.py +118 -0
- silk/lint/rule.py +160 -0
- silk/lint/rules/__init__.py +87 -0
- silk/lint/rules/domain.py +224 -0
- silk/lint/rules/interface.py +402 -0
- silk/lint/rules/stress.py +483 -0
- silk/lint/rules/structural.py +871 -0
- silk/lint/severity.py +49 -0
- silk/lint/stress_coverage.py +159 -0
- silk/lint/violations.py +174 -0
- silk/lint/waivers.py +230 -0
- silk/lint_markers/__init__.py +6 -0
- silk/lint_markers/no_connect.py +26 -0
- silk/lint_markers/no_connect_port.py +55 -0
- silk/lint_markers/stale.py +131 -0
- silk/metrics/__init__.py +440 -0
- silk/metrics/_eye.py +137 -0
- silk/metrics/_guards.py +369 -0
- silk/metrics/ac.py +1714 -0
- silk/metrics/converter.py +1167 -0
- silk/metrics/diagnostics.py +132 -0
- silk/metrics/eye.py +542 -0
- silk/metrics/fom.py +191 -0
- silk/metrics/jitter.py +1121 -0
- silk/metrics/noise.py +1040 -0
- silk/metrics/power.py +258 -0
- silk/metrics/rf.py +1209 -0
- silk/metrics/spectral.py +2402 -0
- silk/metrics/statistics.py +666 -0
- silk/metrics/timing.py +2242 -0
- silk/metrics/waveform.py +1822 -0
- silk/optimize/__init__.py +5 -0
- silk/optimize/optimizer.py +798 -0
- silk/optimize/parameter_space.py +537 -0
- silk/pdk/__init__.py +35 -0
- silk/pdk/_loader.py +180 -0
- silk/pdk/basepdk.py +1455 -0
- silk/pdk/data/gf180mcu.pdk.yaml +207 -0
- silk/pdk/data/gf180mcu_device_details.yaml +2087 -0
- silk/pdk/data/sg13g2.pdk.yaml +91 -0
- silk/pdk/data/sg13g2_device_details.yaml +223 -0
- silk/pdk/data/sky130-internal-node-certificate.yaml +3118 -0
- silk/pdk/data/sky130.pdk.yaml +110 -0
- silk/pdk/data/skywater_130_device_details.yaml +1562 -0
- silk/pdk/registry.py +113 -0
- silk/pdk/statistical.py +117 -0
- silk/pdk/validate.py +802 -0
- silk/settings.py +235 -0
- silk/signals/__init__.py +17 -0
- silk/signals/analysis_kind.py +269 -0
- silk/signals/assemble.py +364 -0
- silk/signals/base.py +2212 -0
- silk/signals/kinds.py +555 -0
- silk/signals/operations.py +121 -0
- silk/signals/rawfile.py +987 -0
- silk/signals/schema.py +800 -0
- silk/signals/spice.py +175 -0
- silk/signals/view/__init__.py +28 -0
- silk/signals/view/__main__.py +325 -0
- silk/signals/view/assets/LICENSE.uPlot +21 -0
- silk/signals/view/assets/explorer.mjs +8367 -0
- silk/signals/view/assets/selectors.mjs +152 -0
- silk/signals/view/assets/uplot.iife.min.js +2 -0
- silk/signals/view/assets/uplot.min.css +1 -0
- silk/signals/view/assets/view.css +1358 -0
- silk/signals/view/assets/view.html.tmpl +26 -0
- silk/signals/view/assets/view.js +64 -0
- silk/signals/view/assets/waveform-core.mjs +732 -0
- silk/signals/view/emit.py +1570 -0
- silk/signals/view/encode.py +282 -0
- silk/signals/view/node_context.py +66 -0
- silk/signals/view/node_select.py +96 -0
- silk/signals/view/select.py +607 -0
- silk/signals/view/serialize.py +65 -0
- silk/signals/view/serve.py +101 -0
- silk/signals/view/template.py +211 -0
- silk/simulation/__init__.py +45 -0
- silk/simulation/_analysis_context.py +52 -0
- silk/simulation/_behavioral_elements.py +239 -0
- silk/simulation/_behavioral_feedback.py +109 -0
- silk/simulation/_behavioral_models.py +94 -0
- silk/simulation/_behavioral_state.py +223 -0
- silk/simulation/_behavioral_variation.py +168 -0
- silk/simulation/_behavioral_views.py +474 -0
- silk/simulation/_device_requests.py +80 -0
- silk/simulation/_failure_detail.py +105 -0
- silk/simulation/_frequency_grid.py +25 -0
- silk/simulation/_internal_nodes.py +165 -0
- silk/simulation/_ngspice_compat.py +175 -0
- silk/simulation/_ngspice_version.py +29 -0
- silk/simulation/_replay.py +289 -0
- silk/simulation/_setup_check.py +137 -0
- silk/simulation/_worker_pickle.py +43 -0
- silk/simulation/analysis.py +484 -0
- silk/simulation/backend.py +2071 -0
- silk/simulation/behavioral.py +637 -0
- silk/simulation/behavioral_backend.py +326 -0
- silk/simulation/completion.py +327 -0
- silk/simulation/conditions.py +1603 -0
- silk/simulation/convergence.py +84 -0
- silk/simulation/corner.py +71 -0
- silk/simulation/executor.py +482 -0
- silk/simulation/generation.py +708 -0
- silk/simulation/launch_fact.py +36 -0
- silk/simulation/mc_chunk.py +411 -0
- silk/simulation/provenance.py +598 -0
- silk/simulation/run_files.py +277 -0
- silk/simulation/runner.py +498 -0
- silk/simulation/topology.py +270 -0
- silk/simulation/variation.py +237 -0
- silk/simulation/xyce_runner.py +361 -0
- silk/simulators/__init__.py +8 -0
- silk/simulators/_loader.py +179 -0
- silk/simulators/behavioral.yaml +20 -0
- silk/simulators/ngspice.yaml +170 -0
- silk/simulators/xyce.yaml +61 -0
- silk/sources/__init__.py +101 -0
- silk/sources/_bits.py +88 -0
- silk/sources/_layout.py +112 -0
- silk/sources/_operating_point.py +47 -0
- silk/sources/_timing.py +100 -0
- silk/sources/classes.py +1375 -0
- silk/sources/library.py +168 -0
- silk/sources/schema.py +383 -0
- silk/sources/source_metadata.yaml +198 -0
- silk/sources/waveforms.py +1625 -0
- silk/specs/__init__.py +47 -0
- silk/specs/_calibration.py +99 -0
- silk/specs/aggregate.py +189 -0
- silk/specs/attempt.py +441 -0
- silk/specs/evidence.py +234 -0
- silk/specs/reconciler.py +246 -0
- silk/specs/report.py +329 -0
- silk/specs/resolver.py +126 -0
- silk/specs/spec.py +627 -0
- silk/spice_names.py +228 -0
- silk/utils/__init__.py +6 -0
- silk/utils/_compat.py +13 -0
- silk/utils/_utils.py +340 -0
- silk/utils/deck_text.py +93 -0
- silk/utils/identifiers.py +21 -0
- silk/vector_match.py +118 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: circuitsilk
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Custom circuit design in Python, from specs to layout
|
|
5
|
+
Author: Levant Labs
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/levantlabs/silk
|
|
8
|
+
Project-URL: Repository, https://github.com/levantlabs/silk
|
|
9
|
+
Project-URL: Documentation, https://github.com/levantlabs/silk/blob/main/docs/quickstart.md
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/levantlabs/silk/issues
|
|
11
|
+
Keywords: spice,analog,eda,sky130,ngspice,circuit,netlist
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: numpy>=1.26
|
|
27
|
+
Requires-Dist: matplotlib
|
|
28
|
+
Requires-Dist: pyyaml
|
|
29
|
+
Requires-Dist: pydantic>=2
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
33
|
+
Requires-Dist: build; extra == "dev"
|
|
34
|
+
Requires-Dist: twine; extra == "dev"
|
|
35
|
+
Provides-Extra: docs
|
|
36
|
+
Requires-Dist: sphinx<9,>=7.2; extra == "docs"
|
|
37
|
+
Requires-Dist: myst-parser<5,>=3; extra == "docs"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# circuitsilk
|
|
41
|
+
|
|
42
|
+
**Custom circuit design in Python, from specs to layout.**
|
|
43
|
+
|
|
44
|
+
circuitsilk (`import silk`) is a framework for custom IC design. A circuit is one live Python object, and that object carries the design through the whole flow: specs, sizing, simulation, verification, reports, design history and layout. Every step is code with typed, checked results, so intelligence — yours, a script's or an AI agent's — can span the entire design flow, not just the netlist.
|
|
45
|
+
|
|
46
|
+
- **Testbenches that live with the circuit.** Each block carries its own tests, metrics and specs; `run_all_tests()` measures everything and reports pass or fail.
|
|
47
|
+
- **Two engines, one workflow.** Iterate in seconds with the built-in behavioral engine (no simulator, no PDK), then run the same testbenches at transistor level in ngspice. Xyce is a preview backend.
|
|
48
|
+
- **Corners, Monte Carlo and design-space search.** PVT corners, Monte Carlo (including behavioral mismatch), sweeps, sampling, and an optimizer that reads testbench metrics directly.
|
|
49
|
+
- **Browser waveform viewer.** Explore signals, cursors and derived expressions in the [interactive viewer](https://github.com/levantlabs/silk/blob/main/docs/waveform-explorer.md).
|
|
50
|
+
- **A full metric library.** Gain, bandwidth and phase margin; SNDR, ENOB, SFDR and INL/DNL for data converters; delay, slew, settling, jitter, noise, distortion and power.
|
|
51
|
+
- **Results you can trust.** silk doesn't take a simulator's exit code on faith. A run that produces no data, or stops before the end of the analysis silk wrote, raises a typed error instead of returning plausible numbers.
|
|
52
|
+
- **Checks beyond simulation.** Analog lint rules (interfaces, voltage domains, junction overrange) and fault-injection campaigns.
|
|
53
|
+
- **Layout (in progress).** Estimated parasitics can be fed into simulation and optimization, and a design's simulated currents and wiring are available for layout.
|
|
54
|
+
- **Design history.** A local SQLite database records versions, metrics and spec results at each PVT point, so a design can be reopened, rebuilt and compared.
|
|
55
|
+
- **Built for AI agents.** Keyword-only APIs that fail loudly, a machine-readable schema export, and an agent guide that walks the whole flow.
|
|
56
|
+
|
|
57
|
+
The whole loop, from system intent to sizing, characterization, reports, database, rebuild and layout feedback, runs in one worked example: `python -m silk.examples.design_loop_walkthrough`.
|
|
58
|
+
|
|
59
|
+
**PDKs.** The PDK layer is pluggable: a new PDK is two data files, not code. For 0.2.0, SkyWater 130nm is the only release-validated transistor-simulation PDK; GF180MCU and SG13G2 ship as preview integrations. Install open-source PDKs with [pdksetup](https://github.com/levantlabs/pdksetup) (`pdk install sky130`).
|
|
60
|
+
|
|
61
|
+
**No PDK yet?** Create and activate a virtual environment, install silk, then
|
|
62
|
+
run a behavioral simulation with no PDK and no ngspice:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python3 -m venv .venv
|
|
66
|
+
source .venv/bin/activate
|
|
67
|
+
python -m pip install "circuitsilk>=0.2"
|
|
68
|
+
python -m silk.examples.behavioral_example
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If `venv` or `ensurepip` is missing, install `python3-venv`
|
|
72
|
+
(`sudo apt install python3-venv`) or ask your administrator, then retry.
|
|
73
|
+
Continue with the [60-second start](https://github.com/levantlabs/silk/blob/main/docs/quickstart.md#1-60-second-start-no-pdk-no-ngspice).
|
|
74
|
+
|
|
75
|
+
## A first transistor-level circuit: a CMOS inverter
|
|
76
|
+
|
|
77
|
+
This example builds a CMOS inverter on sky130, checks its delay against a spec in ngspice, and plots the waveforms. It needs the [Installation](#installation) steps first (ngspice and the sky130 PDK); the behavioral example above needs neither.
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from silk import Module, Port, load_pdk, sources
|
|
81
|
+
from silk.elements import elements
|
|
82
|
+
from silk.metrics import propagation_delay
|
|
83
|
+
from silk.simulation import Transient
|
|
84
|
+
|
|
85
|
+
pdk = load_pdk('sky130') # finds the models through the PDK_ROOT setting
|
|
86
|
+
|
|
87
|
+
# The circuit: a CMOS inverter, as a block with typed ports
|
|
88
|
+
inv = Module('PDK_skywater130', 'out', 'inverter.cir', pdk_details=pdk,
|
|
89
|
+
module_name='inverter')
|
|
90
|
+
inv.define_module_ports({'VDD': Port.supply(), 'VSS': Port.ground(),
|
|
91
|
+
'IN': Port.analog_input(), 'OUT': Port.analog_output()})
|
|
92
|
+
with inv: # devices created here join the inverter
|
|
93
|
+
pdk.nmos1p8('mn', d='OUT', g='IN', s='VSS', b='VSS', w=1.0, l=0.15)
|
|
94
|
+
pdk.pmos1p8('mp', d='OUT', g='IN', s='VDD', b='VDD', w=2.0, l=0.15)
|
|
95
|
+
|
|
96
|
+
# Its testbench: drive it, load it, probe it, and check it against a spec
|
|
97
|
+
tb = inv.create_test('step')
|
|
98
|
+
tb.add_module_under_test({'VDD': 'vdd', 'VSS': '0', 'IN': 'vin', 'OUT': 'vout'})
|
|
99
|
+
tb.add_source(sources.VoltageSource('vdd', positive='vdd', negative='0', dc=1.8))
|
|
100
|
+
tb.add_source(sources.VoltageSource('vin', positive='vin', negative='0',
|
|
101
|
+
pulse=sources.Pulse(v1=0, v2=1.8, td=1e-9, tr=0.5e-9,
|
|
102
|
+
tf=0.5e-9, pw=4e-9, per=10e-9)))
|
|
103
|
+
tb.add(elements.capacitor('cl', p='vout', n='0', value=10e-15))
|
|
104
|
+
tb.add_sim_type(Transient(step=0.01e-9, stop=10e-9))
|
|
105
|
+
tb.set_supply_voltage(1.8, source='vdd')
|
|
106
|
+
|
|
107
|
+
vin, vout = tb.probe('vin'), tb.probe('vout')
|
|
108
|
+
tb.add_metric('delay', propagation_delay, sig_in=vin, sig_out=vout,
|
|
109
|
+
out_edge='falling')
|
|
110
|
+
tb.add_spec('delay < 150 ps', 'delay', '<', 150e-12)
|
|
111
|
+
|
|
112
|
+
report = tb.run() # ngspice, typical corner
|
|
113
|
+
print(f"delay {report.metrics['delay'] * 1e12:.0f} ps: {'PASS' if report.passed else 'FAIL'}")
|
|
114
|
+
print(f'vout swings {vout.y.min():.3f} V to {vout.y.max():.3f} V')
|
|
115
|
+
tb.plot(vin, vout)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For interactive exploration after the run, open the browser viewer:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
tb.netlist.view()
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
For a headless run, use `html_path = tb.netlist.view(open=False)` to return the
|
|
125
|
+
HTML path without opening a browser. By default, `view.html` is written beside
|
|
126
|
+
the rawfile and may have companion files. See the
|
|
127
|
+
[viewer guide](https://github.com/levantlabs/silk/blob/main/docs/waveform-explorer.md).
|
|
128
|
+
Keep `tb.plot(vin, vout)` for a static plot.
|
|
129
|
+
|
|
130
|
+
Expected output:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
delay 91 ps: PASS
|
|
134
|
+
vout swings -0.004 V to 1.816 V
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Continue with [docs/quickstart.md](https://github.com/levantlabs/silk/blob/main/docs/quickstart.md) for the step-by-step workflow.
|
|
138
|
+
|
|
139
|
+
## Installation
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Debian/Ubuntu system pythons are externally managed (PEP 668) — work in a venv:
|
|
143
|
+
python3 -m venv .venv
|
|
144
|
+
source .venv/bin/activate
|
|
145
|
+
|
|
146
|
+
pip install "circuitsilk>=0.2"
|
|
147
|
+
# — or from source —
|
|
148
|
+
git clone https://github.com/levantlabs/silk.git
|
|
149
|
+
cd silk
|
|
150
|
+
pip install -e ".[dev]"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**System requirements:**
|
|
154
|
+
|
|
155
|
+
- Python 3.10–3.13
|
|
156
|
+
- ngspice 42 or newer (for SPICE simulation): check `ngspice --version`.
|
|
157
|
+
If missing or older, install or update it with `sudo apt install ngspice`
|
|
158
|
+
on Debian/Ubuntu, or ask your administrator; then check again.
|
|
159
|
+
It is the release-validated simulator; Xyce is an optional **preview** backend
|
|
160
|
+
([what is and is not validated](https://github.com/levantlabs/silk/blob/main/docs/known_issues.md#simulator-backends))
|
|
161
|
+
- SkyWater 130nm PDK models at `$PDK_ROOT` (for simulations using sky130 devices) —
|
|
162
|
+
see [docs/installing-the-pdk.md](https://github.com/levantlabs/silk/blob/main/docs/installing-the-pdk.md)
|
|
163
|
+
|
|
164
|
+
The `PDK_ROOT` setting should point to a directory that contains
|
|
165
|
+
`sky130A/libs.tech/ngspice/sky130.lib.spice` (the standard open_pdks layout).
|
|
166
|
+
[docs/installing-the-pdk.md](https://github.com/levantlabs/silk/blob/main/docs/installing-the-pdk.md) walks through getting
|
|
167
|
+
there with [pdksetup](https://github.com/levantlabs/pdksetup)
|
|
168
|
+
(`pdk install sky130`), plus Docker and open_pdks alternatives.
|
|
169
|
+
|
|
170
|
+
Tool and PDK locations (`PDK_ROOT`, `SILK_NGSPICE_BIN`, `SILK_XYCE_BIN`, …) are
|
|
171
|
+
silk **settings**: set them as environment variables, or once in a settings
|
|
172
|
+
file at `~/.config/silk/silk.env` so every shell and IDE picks them up. An
|
|
173
|
+
environment variable overrides the file. See
|
|
174
|
+
[docs/settings.md](https://github.com/levantlabs/silk/blob/main/docs/settings.md)
|
|
175
|
+
for the format and a copy-paste example.
|
|
176
|
+
|
|
177
|
+
`load_pdk('sky130')` loads the packaged catalog even without the model files.
|
|
178
|
+
SPICE circuits made only from ideal elements, sources and passives need
|
|
179
|
+
ngspice but no installed PDK; see the
|
|
180
|
+
[PDK-free RC walkthrough](https://github.com/levantlabs/silk/blob/main/docs/quickstart.md#the-middle-rung-real-spice-with-no-pdk).
|
|
181
|
+
Model files are checked when a simulation needs them; a missing library raises
|
|
182
|
+
`SimulationError` with installation advice.
|
|
183
|
+
|
|
184
|
+
Behavioral simulation needs neither ngspice nor PDK models — see the
|
|
185
|
+
[60-second start](https://github.com/levantlabs/silk/blob/main/docs/quickstart.md#1-60-second-start-no-pdk-no-ngspice).
|
|
186
|
+
|
|
187
|
+
To check all of the above at once — interpreter, dependencies, your silk
|
|
188
|
+
settings, ngspice, and the model library of every registered PDK — run the
|
|
189
|
+
environment doctor (exit 0 when
|
|
190
|
+
the setup is ready, and it prints a fix for anything that isn't):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
python -m silk.doctor # add --json for machine-readable output
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Quick start
|
|
197
|
+
|
|
198
|
+
See [docs/quickstart.md](https://github.com/levantlabs/silk/blob/main/docs/quickstart.md) for a step-by-step walkthrough.
|
|
199
|
+
|
|
200
|
+
Find answers by question in the [documentation index](https://github.com/levantlabs/silk/blob/main/docs/README.md), or browse these guides:
|
|
201
|
+
|
|
202
|
+
- [docs/examples.md](https://github.com/levantlabs/silk/blob/main/docs/examples.md) — human-facing guide to the worked
|
|
203
|
+
examples: a learning path plus a by-topic index
|
|
204
|
+
- [docs/cli.md](https://github.com/levantlabs/silk/blob/main/docs/cli.md) — every `python -m` tool (doctor, PDK validator,
|
|
205
|
+
schema exports, waveform explorer) and the `$SILK_NGSPICE_BIN` /
|
|
206
|
+
`$SILK_XYCE_BIN` simulator overrides
|
|
207
|
+
- [docs/database.md](https://github.com/levantlabs/silk/blob/main/docs/database.md) — design-history tracking,
|
|
208
|
+
characterization profiles and PVT selection, close/reopen queries and
|
|
209
|
+
restore, identity, promotion, migration, and JSON scope
|
|
210
|
+
- [docs/known_issues.md](https://github.com/levantlabs/silk/blob/main/docs/known_issues.md) — current limitations, honestly
|
|
211
|
+
- [docs/probes.md](https://github.com/levantlabs/silk/blob/main/docs/probes.md) — declare signals before simulation,
|
|
212
|
+
bind metrics without lambdas, then read or plot results across analyses and corners
|
|
213
|
+
- [CONTRIBUTING.md](https://github.com/levantlabs/silk/blob/main/CONTRIBUTING.md) — dev install (venv, editable, tests) and
|
|
214
|
+
conventions
|
|
215
|
+
|
|
216
|
+
Working examples live in `silk/examples/` and ship in the package — run any of
|
|
217
|
+
them as `python -m silk.examples.<name>`, no checkout needed:
|
|
218
|
+
|
|
219
|
+
| File | What it shows |
|
|
220
|
+
|---|---|
|
|
221
|
+
| `silk/examples/diff_pair_construction_example.py` | Construction-only factory and structure inspection |
|
|
222
|
+
| `silk/examples/factory_api_example.py` | Full factory API: devices, passives, SPICE inspection |
|
|
223
|
+
| `silk/examples/parameter_sweep_example.py` | Design-space sweep with `VariableSpace`/`Variable` |
|
|
224
|
+
| `silk/examples/ldo_design.py` | Parameterized LDO with `Module` + database tracking |
|
|
225
|
+
| `silk/examples/source_examples.py` | All source types: Pulse, Sine, PWL, SFFM, AM, controlled |
|
|
226
|
+
| `silk/examples/pwl_example.py` | PWL waveform: incremental, chaining, tuples, flat list, file |
|
|
227
|
+
| `silk/examples/hierarchical_example.py` | Multi-level subcircuits: inverter → buffer → testbench |
|
|
228
|
+
|
|
229
|
+
## Core concepts
|
|
230
|
+
|
|
231
|
+
### `Module` — the circuit object
|
|
232
|
+
|
|
233
|
+
In silk, a circuit is code. A `Module` is a live Python object holding a block's devices, nets, ports, sources and analyses. Every step of the flow reads that same object: netlisting, simulation, measurement, reports, the design database and layout estimation.
|
|
234
|
+
|
|
235
|
+
Modules are built to be reused. The usual way to write one is a factory function whose design knobs (widths, lengths, bias currents, loads) are keyword arguments, so one function produces every sizing of the block. Each block carries:
|
|
236
|
+
- its **ports**, with direction and role (supply, ground, analog input, output);
|
|
237
|
+
- its **testbenches** (`mod.create_test(...)`), each with its own sources, probes, metrics and specs, so the block knows how to test itself (`mod.run_all_tests()`);
|
|
238
|
+
- optionally a **behavioral model** (`set_behavioral_model`), so the block runs in the fast Python engine before its transistors exist, or stands in for them inside a larger system;
|
|
239
|
+
- its **specs**, which compare designed intent with measured results.
|
|
240
|
+
|
|
241
|
+
Blocks compose with `add_module`, so a system is built from blocks that each bring their own tests and models. And because it is all Python, a design can be diffed, reviewed and versioned like any other code, and read and written by an AI agent as easily as by a person.
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
from silk import Module
|
|
245
|
+
ckt = Module('PDK_skywater130', 'out_dir', 'my_circuit.cir', pdk_details=pdk)
|
|
246
|
+
ckt.add(device1, device2) # add pre-constructed device objects
|
|
247
|
+
ckt.add_source(vsource) # add a voltage or current source
|
|
248
|
+
ckt.add(capacitor) # ideal R, C, L are added with add() too
|
|
249
|
+
ckt.add_sim_type(Transient(...)) # set the simulation type
|
|
250
|
+
ckt.simulate(corner='tt') # generate netlist + run ngspice + load results
|
|
251
|
+
# optional: timeout=300 (seconds)
|
|
252
|
+
ckt.plot('vout', 'vin') # quick multi-panel plot
|
|
253
|
+
sig = ckt.load_signal('v(out)') # retrieve a waveform for custom analysis
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Factory API — device instantiation
|
|
257
|
+
|
|
258
|
+
Devices are instantiated directly from the PDK object. Pins and parameters are
|
|
259
|
+
keyword arguments — IDE autocomplete works on them.
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
mn = pdk.nmos1p8('mn', d='out', g='in', s='gnd', b='gnd', w=1.0, l=0.35, m=4)
|
|
263
|
+
mp = pdk.pmos1p8('mp', d='out', g='in', s='vdd', b='vdd', w=2.0, l=0.35)
|
|
264
|
+
|
|
265
|
+
# Parameters can be updated by direct attribute assignment after construction:
|
|
266
|
+
mn.w = 2.0
|
|
267
|
+
mn.d = 'new_out'
|
|
268
|
+
print(mn.to_spice()) # inspect the SPICE line
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### PDK loading
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
# Option 1: load_pdk (uses the PDK_ROOT setting: env var, settings file, or ~/pdk)
|
|
275
|
+
from silk import load_pdk
|
|
276
|
+
pdk = load_pdk('sky130')
|
|
277
|
+
|
|
278
|
+
# Option 2: override the model-library path
|
|
279
|
+
pdk = load_pdk('sky130', library_location='/path/to/sky130.lib.spice')
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Simulation types
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
from silk.simulation import Transient, AC, DC, Noise, Corner
|
|
286
|
+
|
|
287
|
+
ckt.add_sim_type(Transient(step=1e-9, stop=100e-9))
|
|
288
|
+
ckt.add_sim_type(AC('dec', 100, 1e3, 1e9))
|
|
289
|
+
ckt.add_sim_type(DC(source='vin', start=0, stop=1.8, step=0.01))
|
|
290
|
+
|
|
291
|
+
# Corner is a str-subclass enum — plain strings also work
|
|
292
|
+
ckt.simulate(corner=Corner.TT)
|
|
293
|
+
ckt.simulate(corner='ff') # equivalent
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Sources
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
from silk import sources
|
|
300
|
+
|
|
301
|
+
vs = sources.VoltageSource('vdd', positive='vdd', negative='gnd', dc=1.8)
|
|
302
|
+
cs = sources.CurrentSource('ibias', positive='vdd', negative='vnbias', dc=100e-6)
|
|
303
|
+
|
|
304
|
+
# Waveforms
|
|
305
|
+
vs_pulse = sources.VoltageSource('vin', positive='in', negative='gnd',
|
|
306
|
+
pulse=sources.Pulse(v1=0, v2=1.8, td=0,
|
|
307
|
+
tr=100e-12, tf=100e-12,
|
|
308
|
+
pw=5e-9, per=10e-9))
|
|
309
|
+
vs_sine = sources.VoltageSource('vin', positive='in', negative='gnd',
|
|
310
|
+
sine=sources.Sine(voffset=0, vampl=1, freq=1e6))
|
|
311
|
+
|
|
312
|
+
# Piecewise-linear (PWL) waveform
|
|
313
|
+
pwl = sources.PWL().add(0, 0).add(1e-9, 0).add(2e-9, 1.8).add(10e-9, 1.8)
|
|
314
|
+
vs_pwl = sources.VoltageSource('vin', positive='in', negative='gnd', pwl=pwl)
|
|
315
|
+
# Also accepts: pwl=[(0, 0), (1e-9, 1.8)] or pwl=[0, 0, 1e-9, 1.8]
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Ideal elements (ElementLibrary)
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
from silk.elements import elements
|
|
322
|
+
|
|
323
|
+
r = elements.resistor('r1', p='out', n='gnd', value=10e3)
|
|
324
|
+
c = elements.capacitor('c1', p='out', n='gnd', value=100e-12)
|
|
325
|
+
l = elements.inductor('l1', p='a', n='b', value=1e-9)
|
|
326
|
+
ckt.add(r, c, l)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Construct voltage and current sources with `silk.sources`.
|
|
330
|
+
|
|
331
|
+
### Design-space exploration
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
from silk import Module, load_pdk
|
|
335
|
+
from silk.optimize import VariableSpace
|
|
336
|
+
|
|
337
|
+
pdk = load_pdk('sky130')
|
|
338
|
+
ckt = Module('PDK_skywater130', 'out', 'sweep.cir', pdk_details=pdk)
|
|
339
|
+
|
|
340
|
+
# Create variables with bounds
|
|
341
|
+
w_n = pdk.nmos1p8.w.variable(name='w_n', value=1.0, bounds=(0.42, 20.0))
|
|
342
|
+
w_p = pdk.pmos1p8.w.variable(name='w_p', value=2.0, bounds=(0.42, 20.0))
|
|
343
|
+
l = pdk.nmos1p8.l.variable(name='l', value=0.15, bounds=(0.15, 1.0))
|
|
344
|
+
|
|
345
|
+
# Pass Variable objects directly as device parameters
|
|
346
|
+
with ckt:
|
|
347
|
+
mn = pdk.nmos1p8('mn', d='out', g='in', s='gnd', b='gnd', w=w_n, l=l)
|
|
348
|
+
mp = pdk.pmos1p8('mp', d='out', g='in', s='vdd', b='vdd', w=w_p, l=l)
|
|
349
|
+
|
|
350
|
+
# Build a VariableSpace and sample it
|
|
351
|
+
space = VariableSpace([w_n, w_p, l])
|
|
352
|
+
points = space.sample(20, method='lhs') # Latin hypercube sampling
|
|
353
|
+
# also: method='random', 'halton', 'grid'
|
|
354
|
+
|
|
355
|
+
for pt in points:
|
|
356
|
+
space.apply(pt) # updates variable .value fields
|
|
357
|
+
ckt.generate_netlist(corner='tt') # picks up new values automatically
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Schema export APIs
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
from silk import export_schema, module_schema
|
|
364
|
+
import json
|
|
365
|
+
|
|
366
|
+
# Export all PDK devices as a machine-readable dict
|
|
367
|
+
schema = export_schema(pdk)
|
|
368
|
+
print(json.dumps(schema, indent=2))
|
|
369
|
+
|
|
370
|
+
# Export a single Module's interface
|
|
371
|
+
mod_schema = module_schema(my_module)
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Database / version tracking
|
|
375
|
+
|
|
376
|
+
Pass `db_path` to `Module` to enable database tracking. Python remains the
|
|
377
|
+
authoritative circuit/spec definition; the SQLite file preserves sealed
|
|
378
|
+
snapshot identity, declarations, metric/spec evidence, current sets (multiple
|
|
379
|
+
selected sets per corner, distinguished by characterization profile and
|
|
380
|
+
PVT — see [docs/database.md](https://github.com/levantlabs/silk/blob/main/docs/database.md)), lineage, and provenance.
|
|
381
|
+
Rebuild the same Python definition to restore live state. Unsupported or
|
|
382
|
+
malformed files are rejected without modification; see the database guide's
|
|
383
|
+
[compatibility matrix and migration guidance](https://github.com/levantlabs/silk/blob/main/docs/database.md#file-compatibility).
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
ckt = Module('PDK_skywater130', 'out', 'ldo.cir', pdk_details=pdk,
|
|
387
|
+
module_name='ldo_nmos', db_path='designs.db')
|
|
388
|
+
|
|
389
|
+
ckt.add(mn1, mp1)
|
|
390
|
+
ckt.declare_spec('DC gain', 'gain_dB', '>=', 40.0,
|
|
391
|
+
units='dB', key='gain')
|
|
392
|
+
version_id = ckt.create_circuit_version('Initial attempt')
|
|
393
|
+
ckt.store_results(
|
|
394
|
+
{'gain_dB': (42.5, 'dB')}, source='spice', sim_type='ac',
|
|
395
|
+
corner='tt', temperature=27.0, voltage=1.8,
|
|
396
|
+
tool_name='ngspice-44', conditions={'load_pf': 2.0},
|
|
397
|
+
)
|
|
398
|
+
ckt.close()
|
|
399
|
+
|
|
400
|
+
rebuilt = build_ldo(pdk, db_path='designs.db')
|
|
401
|
+
assert rebuilt.create_circuit_version() == version_id
|
|
402
|
+
rows = rebuilt.query_results(parameter='gain_dB', corner='tt')
|
|
403
|
+
rebuilt.promote('stable') # evidence remains at its origin UUID
|
|
404
|
+
rebuilt.close()
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
JSON export is explicitly a lossy interoperability projection, not a database
|
|
408
|
+
backup or circuit archive. See the canonical [database guide](https://github.com/levantlabs/silk/blob/main/docs/database.md)
|
|
409
|
+
and the simulator-free `python -m silk.examples.circuit_tracking_example`.
|
|
410
|
+
|
|
411
|
+
### Code generation
|
|
412
|
+
|
|
413
|
+
Generate runnable silk Python from a JSON-able spec dict (a circuit description):
|
|
414
|
+
|
|
415
|
+
```python
|
|
416
|
+
from silk.codegen import Generator
|
|
417
|
+
|
|
418
|
+
gen = Generator() # no constructor args
|
|
419
|
+
code = gen.generate({
|
|
420
|
+
'circuit_name': 'diff_pair',
|
|
421
|
+
'pdk': 'sky130',
|
|
422
|
+
'voltage_domains': {'AVDD': {'nominal': 1.8, 'tolerance': 0.1}},
|
|
423
|
+
'ports': {
|
|
424
|
+
'vin_p': {'dir': 'input', 'role': 'analog', 'domain': 'AVDD'},
|
|
425
|
+
'vout': {'dir': 'output', 'role': 'analog', 'domain': 'AVDD'},
|
|
426
|
+
},
|
|
427
|
+
'devices': [...],
|
|
428
|
+
})
|
|
429
|
+
print(code)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Output mode depends on the payload: absent or `null` `ports` emits a standalone simulation script; `ports: {}` emits a zero-pin `Module` subcircuit; non-empty `ports` emits a reusable `Module` subcircuit with those pins and `define_module_ports`. See the [codegen contract](https://github.com/levantlabs/silk/blob/main/docs/codegen-contract.md). Optional `voltage_domains` and `bus_nets` blocks are emitted only when the spec uses them.
|
|
433
|
+
|
|
434
|
+
Full JSON shape and field reference: **[docs/codegen-contract.md](https://github.com/levantlabs/silk/blob/main/docs/codegen-contract.md)**.
|
|
435
|
+
|
|
436
|
+
## Full API reference
|
|
437
|
+
|
|
438
|
+
See [docs/api-reference.md](https://github.com/levantlabs/silk/blob/main/docs/api-reference.md).
|
|
439
|
+
|
|
440
|
+
## Package layout
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
silk/
|
|
444
|
+
__init__.py top-level re-exports
|
|
445
|
+
exceptions.py CircuitError hierarchy
|
|
446
|
+
|
|
447
|
+
circuit/ Module, ModuleTestbench, schema export, port roles, composition graph
|
|
448
|
+
pdk/ BasePDK, load_pdk, PDK manifests + validator
|
|
449
|
+
elements/ ElementLibrary, passives, AnalogElement
|
|
450
|
+
sources/ VoltageSource, CurrentSource, waveforms
|
|
451
|
+
signals/ Signal, NgspiceSignal, rawfile reader, waveform metrics
|
|
452
|
+
simulation/ Transient, AC, DC, Noise, Corner, simulator backends
|
|
453
|
+
simulators/ per-simulator YAML configs (ngspice, xyce)
|
|
454
|
+
specs/ Spec objects, reconciliation, calibration binding
|
|
455
|
+
metrics/ measurement library (ADC, timing, jitter, distortion, noise, …)
|
|
456
|
+
lint/ design-rule framework (stress, port/domain checks, reports)
|
|
457
|
+
faults/ fault injection: FaultSet, FaultCampaign, reports
|
|
458
|
+
layout/ layout estimation, parasitics injection, EM budget
|
|
459
|
+
optimize/ VariableSpace, Variable, Optimizer
|
|
460
|
+
constraints/ constraint vocabulary
|
|
461
|
+
db/ Database, CircuitTracker, CircuitImporter, CircuitExporter, DesignStage
|
|
462
|
+
codegen/ Generator
|
|
463
|
+
utils/ internal helpers
|
|
464
|
+
examples/ runnable example scripts (see docs/agent-guide.md §7)
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Development
|
|
468
|
+
|
|
469
|
+
The test suite lives in the repository, not in the source package. Run these
|
|
470
|
+
commands from the root of a repository clone:
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
pip install -e ".[dev]"
|
|
474
|
+
pytest tests/ -q
|
|
475
|
+
```
|