### Install pcb CLI from source Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/quickstart.mdx Clone the repository, navigate to the source directory, and run the install script to install pcb from source. ```bash # Clone the repo git clone https://github.com/diodeinc/pcb # Move into source folder cd pcb # Run the install script ./install.sh ``` -------------------------------- ### Clone and Install pcb from Source Source: https://github.com/diodeinc/pcb/blob/main/README.md Clone the pcb repository and install it using the provided script. Ensure you have Git installed. ```bash git clone https://github.com/diodeinc/pcb.git cd pcb ./install.sh ``` -------------------------------- ### Complete Board README Example Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/docs_readme.mdx An example of a fully documented board README, including a detailed description, features list, build instructions, and license. This serves as a practical guide for documenting a specific board. ```markdown # DM0001 Motor controller board with STM32F4, dual CAN bus, and hardware ESTOP circuit. Designed for 12V systems with up to 4A continuous motor drive. ## Features - STM32F446 MCU with 180MHz Cortex-M4F - Dual CAN bus with independent termination - Hardware ESTOP with debounce and LED indicator - 3.3V and 1.8V regulated rails from 12V input - SWD debug header and UART console ## Build Instructions ```bash pc b build boards/DM0001 pc b layout boards/DM0001 ``` ## License MIT ``` -------------------------------- ### Inline SPICE Setup with `Simulation()` Source: https://context7.com/diodeinc/pcb/llms.txt Attach a SPICE simulation setup directly to a module for analysis. Nets are referenced using f-string interpolation within the setup string. ```python # modules/LCFilter.zen load("@stdlib/interfaces.zen", "Analog") Inductor = Module("@stdlib/generics/Inductor.zen") Capacitor = Module("@stdlib/generics/Capacitor.zen") VIN = io(Analog, direction="input") VOUT = io(Analog, direction="output") GND = io(Ground) MID = Net() Inductor(name="L1", value="10uH", package="0402", P1=VIN, P2=MID) Capacitor(name="C1", value="100nF", package="0402", P1=VOUT, P2=GND) Capacitor(name="C2", value="10uF", package="0805", P1=VOUT, P2=GND) # Inline SPICE setup — nets referenced by f-string interpolation Simulation( name = "LCFilter_AC", setup = f""" .ac dec 100 1k 100Meg V1 {VIN} {GND} AC 1 .end """, ) ``` -------------------------------- ### Complete Package README Example Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/docs_readme.mdx A comprehensive example of a package README, demonstrating how to document exported symbols, usage, and configuration options. This example illustrates best practices for documenting reusable design modules. ```markdown # power_supply Configurable switch-mode power supply modules for common topologies. ## Usage ```python load("power_supply.zen", "BuckConverter", "BoostConverter") ``` ## Exported Symbols | Symbol | Description | |--------|-------------| | `BuckConverter` | Step-down converter, 4.5–28V input, adjustable output | | `BoostConverter` | Step-up converter, 2.5–5.5V input, up to 12V output | | `BuckBoost` | Buck-boost converter for inputs above or below output | ## Configuration ```python reg = BuckConverter( v_in = Voltage(12), v_out = Voltage(3.3), i_max = Current(3.0), switching_freq = Frequency(500_000), ) ``` ``` -------------------------------- ### Complete Bringup Example Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/docs_bringup.mdx A comprehensive example of a board bringup README, including rework descriptions, firmware flashing instructions, and testing procedures. It demonstrates linking to components using the 'pcb://' scheme and including images. ```markdown # DM0001 v1.0 Bringup Board version v1.0 requires 3 reworks before bringup. Items 1–2 are fixed in v1.1. Item 3 requires a physical fix on each board. ## Reworks ### 1. Short ESTOP debounce resistor (fixed in v1.1) The 47k ESTOP debounce resistor [R_ESTOP_DEBOUNCE](pcb://R_ESTOP_DEBOUNCE) creates a voltage divider with the ESTOP LED, pulling the signal to ~1.5V (below the AND gate VIH threshold of 2.0V). Short across [R_ESTOP_DEBOUNCE](pcb://R_ESTOP_DEBOUNCE) (47k 0402) with a solder blob or wire. Located near the ESTOP connector between ESTOP_RAW and ESTOP nets. ![ESTOP Rework](./images/estop-rework.png) ### 2. Replace decoupling capacitors (fixed in v1.1) [C5](pcb://C5) and [C6](pcb://C6) have insufficient 10uF decoupling for [U1](pcb://U1) LDO. Replace both with 22uF/16V X5R (GRM188R61C226ME15). Bottom side, adjacent to [U1](pcb://U1). ### 3. CAN termination resistor [R12](pcb://R12) footprint is unpopulated. Add 120 ohm 0402 resistor for CAN bus termination. ## Firmware ### Prerequisites - J-Link programmer - Firmware v1.0.2: `dm0001-v1.0.2.bin` ### Flash Procedure 1. Connect J-Link to SWD header [J5](pcb://J5) 2. Power board via 12V supply 3. Run: `JFlash -openprj dm0001.jflash -open dm0001-v1.0.2.bin -auto -exit` 4. Verify: LED [D1](pcb://D1) should blink at 1Hz after flash ## Testing ### Power Rail Verification | Rail | Test Point | Expected | Tolerance | |------|-----------|----------|-----------| | 3.3V | [TP1](pcb://TP1) | 3.30V | ±50mV | | 1.8V | [TP2](pcb://TP2) | 1.80V | ±30mV | | 5.0V | [TP3](pcb://TP3) | 5.00V | ±100mV | ### CAN Bus Test 1. Connect CAN analyzer to [J2](pcb://J2) 2. Send test frame: ID=0x100, DLC=8, data=0xFF 3. Board should echo back on ID=0x101 within 10ms ### ESTOP Functional Test 1. Short ESTOP connector pins 1-2 2. Verify ESTOP_OUT test point reads 3.3V (after rework #1) 3. Open ESTOP connector 4. Verify ESTOP_OUT reads 0V ``` -------------------------------- ### Install pcb CLI using PowerShell Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/quickstart.mdx Use this command to download and execute the latest pcb installer script via PowerShell. ```powershell powershell -ExecutionPolicy Bypass -c "irm https://github.com/diodeinc/pcb/releases/latest/download/pcb-installer.ps1 | iex" ``` -------------------------------- ### Board Setup Settings Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-sexpr/src/doc/sexpr-pcb.adoc The setup section stores board-specific settings like default item sizes and other options. This includes parameters for stack-up, pad clearances, solder mask width, and plotting settings. ```lisp (setup [(STACK_UP_SETTINGS)] (pad_to_mask_clearance CLEARANCE) [(solder_mask_min_width MINIMUM_WIDTH)] [(pad_to_paste_clearance CLEARANCE)] [(pad_to_paste_clearance_ratio RATIO)] [(aux_axis_origin X Y)] [(grid_origin X Y)] (PLOT_SETTINGS) ) ``` -------------------------------- ### Minimal README Usage Example Source: https://github.com/diodeinc/pcb/blob/main/skills/reference-design/SKILL.md A basic example demonstrating how to instantiate a module in Python, typically found in a component's README file for usage guidance. ```python MyRef = Module("github.com/diodeinc/registry/components//.zen") MyRef( name="U1", VIN=vin, VOUT=vout, GND=gnd, ) ``` -------------------------------- ### Install pcb CLI Source: https://context7.com/diodeinc/pcb/llms.txt Installs the pcb binary using a script. Supports macOS, Linux, and Windows. Can also be installed from source or self-updated. ```bash # macOS / Linux curl --proto '=https' --tlsv1.2 -LsSf \ https://github.com/diodeinc/pcb/releases/latest/download/pcb-installer.sh | sh ``` ```powershell # Windows (PowerShell) powershell -ExecutionPolicy Bypass -c \ "irm https://github.com/diodeinc/pcb/releases/latest/download/pcb-installer.ps1 | iex" ``` ```bash # From source git clone https://github.com/diodeinc/pcb.git && cd pcb && ./install.sh ``` ```bash # Self-update pcb self update ``` -------------------------------- ### Module Definition Example Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Example of a Zen module defining configuration, electrical interface, and internal nets. It imports other modules and uses `config()` and `io()` to set up its interface. ```python # modules/LedIndicator.zen Resistor = Module("@stdlib/generics/Resistor.zen") Led = Module("@stdlib/generics/Led.zen") # Configuration color = config(str, default="red") r_value = config(str, default="330ohms") # Electrical interface VCC = io(Power) GND = io(Ground) # Internal net led_anode = Net("LED_ANODE") ``` -------------------------------- ### Install pcb CLI using curl Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/quickstart.mdx Use this command to download and execute the latest pcb installer script via curl. ```bash curl --proto '=https' --tlsv1.2 -LsSf https://github.com/diodeinc/pcb/releases/latest/download/pcb-installer.sh | sh ``` -------------------------------- ### Dependency Resolution Example Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/packages.mdx Illustrates how multiple semver families are handled during dependency resolution, showing how different versions of the same package can coexist. ```plaintext WV0001: stdlib = 0.2.13 WV0002: stdlib = 0.3.2, regulator = 1.0 WV0003: stdlib = 0.3.1 regulator@1.0.0: stdlib = 0.3.0 Result: v0.2.x family → stdlib@0.2.13 v0.3.x family → stdlib@0.3.2 (max of 0.3.2, 0.3.1, 0.3.0) ``` -------------------------------- ### Project Structure Example Source: https://context7.com/diodeinc/pcb/llms.txt Illustrates a typical Zener project directory layout, including workspace manifest, dependency lockfile, boards, modules, and components. ```tree my-project/ ├── pcb.toml # Workspace manifest ├── pcb.sum # Dependency lockfile (commit to VCS) ├── boards/MainBoard/ │ ├── pcb.toml │ ├── MainBoard.zen │ └── layout/ # KiCad layout files ├── modules/PowerSupply/ │ ├── pcb.toml │ └── PowerSupply.zen └── components/TPS54331/ ├── pcb.toml └── TPS54331.zen ``` -------------------------------- ### Zener Simulation Property Setup Source: https://github.com/diodeinc/pcb/blob/main/skills/spice-sim/SKILL.md Defines a Simulation property in Zener, passing raw ngspice commands to the `setup` string for analysis and control. ```python load("@stdlib/properties.zen", "Simulation") Simulation( name="SIM", setup=""" * raw ngspice goes here .control tran 10u 10m .endc """, ) ``` -------------------------------- ### Basic Spinner Usage Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-ui/README.md Create and manage a simple spinner with default settings. Start the spinner, perform work, and then indicate success. ```rust use diode_ui::Spinner; let spinner = Spinner::builder("Processing...").start(); // ... do work ... spinner.success("Done!"); ``` -------------------------------- ### Attach Simulation Setup and Modifiers Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Attach inline simulation setup and component modifiers to the current module. `Simulation()` uses the same BOM-profile hook as `Layout()`. ```python Simulation(name="my_simulation", setup=None, modifiers=None, bom_profile=...) ``` -------------------------------- ### Generic Component Matching Example Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-ipc2581-tools/README.md An example of a 'Generic' key within the BOM rules JSON, used for matching components based on their specifications like package type, component type, capacitance, and tolerance. ```json { "key": { "Generic": { "package": "0402", "component_type": "Capacitor", "capacitance": {"value": "100e-9", "unit": "F", "tolerance": "0.1"} } }, "offers": [ {"manufacturer": "Murata", "manufacturer_pn": "GRM155R71C104KA88D", "rank": 1} ] } ``` -------------------------------- ### Create a Basic Blinky Zener Design Source: https://github.com/diodeinc/pcb/blob/main/README.md Define a simple circuit with a resistor and an LED connected to power and ground using the Zener language. This example requires the `pcb-version` to be set in the workspace configuration. ```python # ```pcb # [workspace] # pcb-version = "0.3" # ``` Resistor = Module("@stdlib/generics/Resistor.zen") Led = Module("@stdlib/generics/Led.zen") VCC = Power() GND = Ground() LED_ANODE = Net() Resistor(name="R1", value="1kohm", package="0402", P1=VCC, P2=LED_ANODE) Led(name="D1", package="0402", color="red", A=LED_ANODE, K=GND) Board(name="blinky", layers=4, layout_path="layout/blinky") ``` -------------------------------- ### Run SPICE Simulations with pcb simulate Source: https://context7.com/diodeinc/pcb/llms.txt Compiles a .zen file with an inline Simulation() setup and runs it through ngspice. Use --netlist to print the netlist without running ngspice, -o to write the netlist to a file, and --verbose for full ngspice output. ```bash pcb simulate circuits/Filter.zen ``` ```bash pcb simulate circuits/Filter.zen --netlist ``` ```bash pcb simulate circuits/Filter.zen -o filter.cir ``` ```bash pcb simulate circuits/Filter.zen --verbose ``` -------------------------------- ### Basic Registry Search Usage Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-diode-api/README.md Demonstrates how to initialize the RegistryClient and perform a general search for a component. ```rust use pcb_diode_api::{RegistryClient, ParsedQuery}; // Open registry (downloads if not present) let client = RegistryClient::open()?; // Search with automatic preprocessing let results = client.search("STM32G431", 25)?; ``` -------------------------------- ### Build .zen Designs with PCB CLI Source: https://github.com/diodeinc/pcb/blob/main/AGENTS.md Use this command to build and validate .zen designs. Specify the paths to the designs you want to process. ```bash cargo run -p pcb -- build [PATHS...] ``` -------------------------------- ### Import KiCad Projects with pcb import Source: https://context7.com/diodeinc/pcb/llms.txt Converts an existing KiCad project into a Zener workspace. Creates a full Zener workspace scaffold from the KiCad project. ```bash pcb import path/to/project.kicad_pro output_dir/ ``` -------------------------------- ### Terminal Utilities API Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-ui/README.md Utilities for interacting with the terminal, such as getting size, truncating, and padding text. ```APIDOC ## Terminal Utilities ### Description Provides functions for terminal size detection and text manipulation. ### Usage **Get Terminal Size:** ```rust use diode_ui::terminal; if let Some(size) = terminal::get_terminal_size() { println!("Terminal: {}x{}", size.width, size.height); } ``` **Text Manipulation:** ```rust use diode_ui::terminal; let truncated = terminal::truncate_text("Long text here", 10); // "Long te..." let padded = terminal::pad_text("Hi", 10, terminal::Alignment::Center); // " Hi " ``` **Calculate Display Width:** ```rust use diode_ui::terminal; let width = terminal::text_width("Hello 世界"); // Accounts for wide chars ``` ``` -------------------------------- ### PCB Board Configuration with `Board()` Source: https://context7.com/diodeinc/pcb/llms.txt Configure PCB stackup, design rules, and layout path. Supports simple usage with default settings or custom configurations using `BoardConfig`. ```python # Simple usage — picks sensible defaults for the layer count Board(name="my_board", layers=4, layout_path="layout/my_board") # Layers: 2, 4, 6, or 8 Board(name="hf_board", layers=6, layout_path="layout/hf_board") # Custom board configuration using BoardConfig load("@stdlib/board_config.zen", "BoardConfig", "DesignRules", "Stackup", "NetClass", "CopperLayer", "DielectricLayer", "Material", "Constraints", "Copper", "Holes", "BASE_CONSTRAINTS", "BASE_4L_STACKUP", "BASE_4L_NETCLASSES") custom_config = BoardConfig( stackup = BASE_4L_STACKUP, design_rules = DesignRules( constraints = BASE_CONSTRAINTS, netclasses = BASE_4L_NETCLASSES + [ NetClass( name = "USB_DP_DM", track_width = 0.1867, diff_pair_width = 0.1867, diff_pair_gap = 0.127, differential_pair_impedance = Impedance(90), ), ], ), ) Board(name="my_board", layout_path="layout/my_board", config=custom_config) ``` -------------------------------- ### TOML Dependency Declaration Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Example of declaring remote package versions in `pcb.toml`. This ensures stable imports across upgrades. ```toml [dependencies] "github.com/diodeinc/registry/reference/TPS54331" = "1.0" ``` -------------------------------- ### pcb:sch Position Comment Examples Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-sch/README.md Illustrates the usage of the pcb:sch comment format for specifying component positions and orientations. ```text # pcb:sch R1 x=100.0000 y=200.0000 rot=0 ``` ```text # pcb:sch U1 x=150.0000 y=80.0000 rot=90 mirror=x ``` -------------------------------- ### Build and Layout Board Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/antenna_matching_network.mdx Build and lay out the board using the pcb CLI commands. This process generates the board layout, which can then be opened in KiCad for tuning and refinement. ```bash pcb build boards/AntennaDemo/AntennaDemo.zen pc b layout boards/AntennaDemo/AntennaDemo.zen ``` -------------------------------- ### Basic KiCad PCB S-expression Structure Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-sexpr/src/doc/sexpr-pcb.adoc This is a basic example of the root s-expression for a KiCad PCB file, including version and host information. ```sexpr (kicad_pcb (version 3) (host pcbnew "(2013-02-20 BZR 3963)-testing") ``` -------------------------------- ### Import Web Component Source: https://github.com/diodeinc/pcb/blob/main/skills/component-search/SKILL.md Imports a web component into the workspace, downloading necessary models and generating package files. If the component already exists, it reports the existing path. ```bash pcb new component --component-id --part-number --manufacturer ``` -------------------------------- ### Snap Values to E-Series Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Utilize functions from `@stdlib/utils.zen` to snap values to standard resistor/capacitor E-series. For example, `e96()` finds the nearest E96 value. ```python load("@stdlib/utils.zen", "e96") r = e96(Resistance("4.8k")) # → 4.87kΩ (nearest E96 value) ``` -------------------------------- ### Instantiate a Module Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Instantiate a module from a local path and connect its power and ground pins to global power sources. This is typically done within a parent board definition. ```python LedIndicator = Module("./modules/LedIndicator.zen") vcc = Power("VCC_3V3", voltage="3.3V") gnd = Ground("GND") LedIndicator(name="LED1", VCC=vcc, GND=gnd, color="green") LedIndicator(name="LED2", VCC=vcc, GND=gnd, color="red") Board(name="MainBoard", layers=4, layout_path="layout/MainBoard") ``` -------------------------------- ### Format .zen Files with PCB CLI Source: https://github.com/diodeinc/pcb/blob/main/AGENTS.md Use this command to format .zen files. Specify the paths to the files you want to format. ```bash cargo run -p pcb -- fmt [PATHS...] ``` -------------------------------- ### Display Workspace and Package Information with PCB Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/packages.mdx Execute `pcb info` to view summary details of your workspace or specific package information. Use `--format json` for machine-readable output. ```bash pcb info # Show workspace summary ``` ```bash pcb info --format json # Machine-readable output ``` -------------------------------- ### ngspice PWL Source Example Source: https://github.com/diodeinc/pcb/blob/main/skills/spice-sim/SKILL.md Defines a PWL (Piecewise Linear) voltage source for ngspice, specifying time-voltage pairs to create a custom waveform. ```spice V_IN VIN GND PWL(0 12 5m 12 5.1m 22 10m 22 10.1m 12 15m 12 15.1m 2 20m 2) ``` -------------------------------- ### Instantiate Hierarchical Subcircuit Module Source: https://context7.com/diodeinc/pcb/llms.txt Use `Module()` to load and instantiate other `.zen` files as subcircuits. Pass nets and configuration values by keyword arguments. Ensure the module path is correct. ```python # boards/MainBoard/MainBoard.zen RCFilter = Module("./modules/RCFilter.zen") HighSideSense = Module("./modules/HighSideSense.zen") TPS54331 = Module("github.com/diodeinc/registry/reference/TPS54331/TPS54331.zen") ``` ```python VCC = Power("VCC_3V3", voltage="3.3V") GND = Ground() ``` ```python SIG_IN = Analog() SIG_OUT = Analog() ``` ```python # Pass io() nets and config() values by keyword RCFilter(name="LPF1", r_value="1kohms", c_value="100nF", INPUT=SIG_IN, OUTPUT=SIG_OUT, GND=GND) ``` ```python TPS54331(name="BUCK1", VIN=Power("VIN_5V", voltage="5V"), VOUT=VCC, GND=GND, output_voltage="3.3V") ``` ```python Board(name="MainBoard", layers=4, layout_path="layout/MainBoard") ``` -------------------------------- ### Run Rust Integration Tests for Layout Generation Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-layout/README.md Execute Rust integration tests for end-to-end PCB layout generation. These tests require KiCad to be installed. ```bash # All layout tests cargo test --package pcb-layout ``` ```bash # Specific test files: cargo test --package pcb-layout layout_generation # Main layout scenarios ``` ```bash cargo test --package pcb-layout fpid_change # FPID change handling ``` ```bash cargo test --package pcb-layout moved # moved() path handling ``` -------------------------------- ### Custom Matcher Function Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/testing.mdx Define custom logic for path validation by creating a matcher function. This example checks for a resistor component and consumes one component. ```python def custom_matcher(path, cursor): if cursor >= len(path.components): error("path ended, expected component") component = path.components[cursor] check(component.type == "resistor", "Expected resistor") return 1 # Components consumed ``` -------------------------------- ### Import Paths for Modules Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Demonstrates various import path syntaxes for local files, stdlib, and remote packages. Remote package versions are managed separately in `pcb.toml`. ```python # Local file (relative to current file) load("./utils.zen", "helper") # Stdlib (version controlled by toolchain) load("@stdlib/units.zen", "Voltage", "Resistance") load("@stdlib/interfaces.zen", "Spi") # Remote packages (version declared in pcb.toml) Resistor = Module("@stdlib/generics/Resistor.zen") TPS54331 = Module("github.com/diodeinc/registry/reference/TPS54331/TPS54331.zen") ``` -------------------------------- ### Datasheet Validation: Feedback Network Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/testing.mdx Validate feedback resistor divider networks. This example checks for a basic two-resistor divider topology connected to the feedback pin. ```python def validate_feedback_divider(module: Module): graph = module.graph() fb_paths = graph.paths(start=("TPS82140", "VOUT"), end=("TPS82140", "FB")) # Resistor divider topology fb_paths[0].matches( is_resistor(), is_resistor() ) ``` -------------------------------- ### Importing Packages in Zen Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/packages.mdx Demonstrates how to import modules using their global import paths. This approach avoids a central registry and provides unambiguous origin for code. ```python load("github.com/diodeinc/stdlib/units.zen", "Voltage") load("github.com/myorg/components/capacitor.zen", "Capacitor") ``` -------------------------------- ### Styled Text Examples Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-ui/README.md Apply consistent styling to text messages using predefined styles for success, error, warning, and info. Custom styles can also be applied. ```rust use diode_ui::prelude::*; println!("{}", "Success!".success()); // ✓ Success! (green) println!("{}", "Error!".error()); // ✗ Error! (red) println!("{}", "Warning!".warning()); // ! Warning! (yellow) println!("{}", "Info".info()); // ℹ Info (blue) // Or use specific styles use diode_ui::{Style, StyledText}; println!("{}", "Custom".with_style(Style::Cyan)); ``` -------------------------------- ### Datasheet Validation: Power Supply Decoupling Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/testing.mdx Validate power supply decoupling components according to datasheet recommendations. This example checks for the presence of bulk and ceramic capacitors. ```python def validate_vin_decoupling(module: Module): """Validate VIN decoupling per datasheet""" graph = module.graph() vin_paths = graph.paths(start=("TPS82140", "VIN"), end="GND_GND") # Datasheet: "10uF bulk + 100nF ceramic" vin_paths.any(path.matches(is_capacitor("10uF"))) vin_paths.any(path.matches(is_capacitor("100nF"))) ``` -------------------------------- ### Application Pipeline Phases Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-layout/README.md Illustrates the sequential phases involved in applying changesets to the PCB layout. ```text Phase 1: Deletions ├── GR-REMOVE (delete group + all contents) └── FP-REMOVE (delete standalone footprints) Phase 2: Additions ├── FP-ADD (create at origin) └── GR-ADD (create empty group) Phase 3: View updates └── Update metadata on existing footprints Phase 4: Group membership rebuild └── Rebuild parent→child relationships Phase 5: Pad-to-net assignments └── Connect pads to their nets Phase 6: HierPlace positioning ├── Position inheritance (FPID changes) ├── Fragment positions (PLACE_FP_FRAGMENT) ├── Orphan packing (PLACE_FP_ORPHAN) ├── Hierarchical layout (bottom-up packing) └── Fragment group moves (PLACE_GR) Phase 7: Fragment routing └── Apply tracks/vias/zones from layout fragments (offset by group move) ``` -------------------------------- ### Inspect Board Information Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-ipc2581-tools/README.md Use the 'info' command to get a summary of the PCB board, including dimensions, components, layers, and drills. Supports custom units and JSON output. ```bash pcb ipc2581 info board.xml ``` ```bash pcb ipc2581 info board.xml --units mil --format json ``` -------------------------------- ### Zener Testbench Pattern Source: https://github.com/diodeinc/pcb/blob/main/skills/spice-sim/SKILL.md A comprehensive Zener testbench pattern including module instantiation, external load, and simulation setup with ngspice commands for transient analysis and SVG hardcopy output. ```python """ simulation test.""" load("@stdlib/interfaces.zen", "Ground", "Power") load("@stdlib/properties.zen", "Simulation") Target = Module("../Target.zen") Resistor = Module("@stdlib/generics/Resistor.zen") VIN = Power(voltage="12V") VOUT = Power() GND = Ground() Target( name="UUT", VIN=VIN, VOUT=VOUT, GND=GND, ) Resistor( name="R_LOAD", value="10ohm", package="0603", P1=VOUT, P2=GND, ) Simulation( name="SIM", setup=""" * V_IN VIN GND DC 12 .control tran 10u 10m set hcopydevtype = svg hardcopy output/.svg v(VIN) v(VOUT) title " " xlabel "Time" ylabel "Voltage" .endc """, ) ``` -------------------------------- ### Load and Instantiate Modules Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Use `Module()` to load reusable subcircuits from `.zen` files. Instantiate them by providing a name and passing arguments corresponding to the module's `io()` and `config()` declarations. ```python PowerSupply = Module("./modules/PowerSupply.zen") TPS54331 = Module("github.com/diodeinc/registry/reference/TPS54331/TPS54331.zen") PowerSupply(name="PSU1", VIN=vin, VOUT=vout, GND=gnd, output_voltage="3.3V") ``` -------------------------------- ### ngspice PULSE Source Example Source: https://github.com/diodeinc/pcb/blob/main/skills/spice-sim/SKILL.md Defines a PULSE voltage source for ngspice, specifying initial voltage, pulsed voltage, delay time, rise time, fall time, pulse width, and period. ```spice V_IN VIN GND DC 5.3 V_ON ON GND PULSE(0 0.9V 1ms 10us 10us 3ms 5ms) ``` -------------------------------- ### Instantiate Schematic Modules with Module() Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Use `Module()` to create instantiable subcircuits from schematic modules. Requires the module path and component parameters. ```python Resistor = Module("@stdlib/generics/Resistor.zen") Resistor(name="R1", value="10k", P1=vcc, P2=gnd) ``` -------------------------------- ### Instantiate a Component with Pins and Part Info Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Use Component() to represent physical electronic parts. Specify name, symbol, pins, and optionally part details for sourcing and footprint. ```python Component( name = "U1", symbol = my_symbol, pins = { "VCC": vcc, "GND": gnd, "OUT": output_net, }, prefix = "U", part = Part(mpn="LM358", manufacturer="TI"), ) ``` -------------------------------- ### Define a Track Segment in S-expression Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-sexpr/src/doc/sexpr-pcb.adoc Use the `segment` token to define a track segment. It requires start and end coordinates, width, layer, net, and a unique timestamp. An optional `locked` token can prevent editing. ```sexpr (segment (start X Y) (end X Y) (width WIDTH) (layer LAYER_DEFINITION) [(locked)] (net NET_NUMBER) (tstamp UUID) ) ``` -------------------------------- ### Define a Track Arc in S-expression Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-sexpr/src/doc/sexpr-pcb.adoc Use the `arc` token to define a track arc. It requires start, mid, and end points, width, layer, net, and a unique timestamp. An optional `locked` token can prevent editing. ```sexpr (arc (start X Y) (mid X Y) (end X Y) (width X Y) (layer LAYER_DEFINITION) [(locked)] (net NET_NUMBER) (tstamp UUID) ) ``` -------------------------------- ### Create New Project Elements Source: https://context7.com/diodeinc/pcb/llms.txt Commands to create new workspace, board, or package elements within a Zener project. ```bash pcb new workspace my-project --repo github.com/myorg/my-project pc b new board MainBoard pc b new package modules/PowerSupply ``` -------------------------------- ### Run pcb-docgen CLI Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-docgen/README.md Execute the pcb-docgen tool from the command line. Specify input stdlib path, output docs directory, and the pcb CLI path. ```bash cargo run -p pcb-docgen cargo run -p pcb-docgen -- ``` -------------------------------- ### Semver Families Example Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/packages.mdx Illustrates how compatible versions of a package form a semver family. Versions within the same family are interchangeable, while different families may be incompatible. The system selects the highest version within a family when multiple are required. ```plaintext v0.3.x family: 0.3.0, 0.3.1, 0.3.2, ... (compatible) v0.4.x family: 0.4.0, 0.4.1, ... (compatible) v0.3.x and v0.4.x: different families (potentially incompatible) ``` -------------------------------- ### Migrate Legacy V1 Project Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/packages.mdx Upgrade a V1 project to the V2 format using the `pcb migrate` command. This updates `pcb.toml` and `.zen` files. ```bash pcb migrate # Migrate current workspace pc b migrate ./path/to/workspace ``` -------------------------------- ### Building a PCB Component Package Source: https://github.com/diodeinc/pcb/blob/main/skills/reference-design/SKILL.md Command to build a component package. It's recommended to build iteratively after major blocks to catch issues early. ```bash pcb build components/ ``` -------------------------------- ### View Embedded Documentation with pcb doc Source: https://context7.com/diodeinc/pcb/llms.txt Browse Zener language documentation with fuzzy search. Can jump to the language spec, view docs for a specific package, view release notes, or list .zen files in a package. ```bash pcb doc ``` ```bash pcb doc spec ``` ```bash pcb doc --package @stdlib ``` ```bash pcb doc --changelog ``` ```bash pcb doc --package @stdlib --list ``` -------------------------------- ### Scaffolding a New PCB Component Package Source: https://github.com/diodeinc/pcb/blob/main/skills/reference-design/SKILL.md Command to generate a new component package scaffold. Use this when creating a fresh component, and evolve existing packages instead of creating siblings. ```bash pcb new package components/ ``` -------------------------------- ### Build a Board or Workspace Member with PCB Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/packages.mdx Use `pcb build` to compile your project. It automatically handles dependencies and lockfile verification. Specify a board path for targeted builds or use `--offline` to build using only cached packages. ```bash pcb build # Build default board ``` ```bash pcb build boards/WV0002 # Build specific board ``` ```bash pcb build --offline # Build using only cached/vendored packages ``` -------------------------------- ### Configure Board Parameters Source: https://github.com/diodeinc/pcb/blob/main/docs/pages/spec.mdx Configure PCB manufacturing parameters such as the number of layers and the path to the layout file. This serves as a prelude symbol for board definitions. ```python Board(name="my_board", layers=4, layout_path="layout/my_board") ``` -------------------------------- ### Run Lens Sync Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-layout/README.md Execute the lens synchronization process with provided board and netlist data. Requires KiCad environment and specific configuration maps. ```python from lens import run_lens_sync result = run_lens_sync( netlist=netlist, kicad_board=board, pcbnew=pcbnew, board_path=board_path, footprint_lib_map=footprint_lib_map, groups_registry=groups_registry, ) ``` -------------------------------- ### Instantiate Generic Components Source: https://context7.com/diodeinc/pcb/llms.txt Use generic component modules from `@stdlib/generics/` for passives and common discretes. This provides automatic BOM matching. Ensure correct parameters like value, package, and pin connections are provided. ```python Resistor = Module("@stdlib/generics/Resistor.zen") Capacitor = Module("@stdlib/generics/Capacitor.zen") Inductor = Module("@stdlib/generics/Inductor.zen") Led = Module("@stdlib/generics/Led.zen") Rectifier = Module("@stdlib/generics/Rectifier.zen") # Schottky / standard diodes Zener = Module("@stdlib/generics/Zener.zen") Tvs = Module("@stdlib/generics/Tvs.zen") Crystal = Module("@stdlib/generics/Crystal.zen") ``` ```python VCC = Power("VCC_3V3", voltage="3.3V") GND = Ground() ``` ```python Resistor(name="R1", value="10k", package="0603", P1=VCC, P2=GND) ``` ```python Capacitor(name="C1", value="100nF", package="0402", voltage="16V", P1=VCC, P2=GND) ``` ```python Inductor(name="L1", value="4.7uH", package="0402", P1=VCC, P2=GND) ``` ```python Led(name="D1", color="red", package="0402", A=sig, K=GND) ``` ```python Rectifier(name="D2", package="DO-214AC", technology="Schottky", reverse_voltage="40V", forward_current="1A", forward_voltage="500mV", A=anode, K=cathode) ``` ```python Zener(name="D3", package="SOD-123", zener_voltage="5.1V", A=GND, K=rail) ``` ```python Tvs(name="D4", package="DO-214AA", direction="Unidirectional", reverse_standoff_voltage="24V", peak_pulse_power="3000W", A=GND, K=VIN) ``` -------------------------------- ### Compare Layout Snapshots Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-layout/README.md Utilize a Python script to compare PCB layout snapshots, distinguishing between structural and positional differences. Useful for reviewing changes between branches. ```bash # Compare current file against main branch python crates/pcb-layout/src/scripts/compare_layout_snapshots.py main HEAD path/to/snapshot.snap ``` ```bash # Compare all layout snapshots between branches python crates/pcb-layout/src/scripts/compare_layout_snapshots.py main HEAD --all ``` ```bash # Verbose output (show all position changes) python crates/pcb-layout/src/scripts/compare_layout_snapshots.py main HEAD --all -v ``` -------------------------------- ### Help Strings for Zener Configs Source: https://github.com/diodeinc/pcb/blob/main/skills/idiomatic-zener/SKILL.md Use `help=` when it adds integrator-visible meaning not obvious from name, type, or default. Omit it when it would just restate those fields. ```zen VDD = io(Power(voltage="3.0V to 5.5V")) GND = io(Ground) EN = io(Net, help="High to enable the regulator") input_filter = config(Frequency, default="0Hz", optional=True, help="Input lowpass cutoff. 0Hz disables the filter.") ``` -------------------------------- ### Zener Physical Unit Constructors Source: https://github.com/diodeinc/pcb/blob/main/skills/zener-language/SKILL.md Demonstrates the construction of physical unit types like Voltage, Resistance, and Capacitance. Supports point values, ranges, and specific notations like '4k7' for 4.7kΩ. Ranges can include an explicit nominal value. ```python Voltage("3.3V") # point value Resistance("4k7") # 4.7kΩ resistor notation Capacitance("100nF") Voltage("1.1–3.6V") # range Voltage("11–26V (12V)") # range with explicit nominal ``` -------------------------------- ### Define PCB Stack Up Settings Source: https://github.com/diodeinc/pcb/blob/main/crates/pcb-sexpr/src/doc/sexpr-pcb.adoc Use the `stackup` token to define the board's layer stack up. This includes layer definitions, copper finish, dielectric constraints, and edge connector properties. ```sexpr (stackup (LAYER_STACK_UP_DEFINITIONS) <1> [(copper_finish "FINISH")] <2> [(dielectric_constraints yes | no)] <3> [(edge_connector yes | bevelled)] <4> [(castellated_pads yes)] <5> [(edge_plating yes)] <6> ) ```