diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..ae7308cf1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,56 @@ +# Contribution Guidelines + +We take pull requests! + +All pull requests are thoroughly reviewed for code quality. + + +## Parts Contributions + +This repository maintains a curated parts library since: +- parts represent a continuing maintenance commitment +- we want libraries to produce working boards with reasonably high confidence +- we want to avoid choice overload for users + +There will be many useful parts that are not a good fit for inclusion on this repository, but we encourage an ecosystem of community libraries. +Consider creating a separate repository and publishing it on pip with a dependency on this project. +We may maintain a list of high quality third-party parts libraries. + +Good candidates for inclusion in this repository are: +- parts with good support among the maker and open-source community, such as support in ESPHome or high quality Arduino or Rust libraries +- parts with breakout boards available, such as by Sparkfun or Adafruit +- parts available from many distributors, including JLC assembly (particularly basic parts), Mouser, and Digi-Key +- parts with wide applicability +- parts using footprints in the standard KiCad libraries, or in PCM libraries +- parts that have been tested functional in a real PCB, consider opening PRs after you've brought up your device + +Parts that are poor candidates for inclusion are: +- parts that cannot be sourced by individuals +- parts with no public documentation (community-provided documentation and libraries count) +- parts that cannot be hand-soldered (including with hot air), primarily BGA +- extremely integrated parts which do not have a clean block boundary or interface +- niche parts + +Borderline case? Feel free to open an issue or PR for discussion. + + +## Compiler / Infrastructure Contributions + +If you're thinking of implementing a significant feature or refactor, please discuss the plan with us first such as through an issue. +We'd prefer to figure out and nail down an architecture and plan before any detailed coding. + + +## Third Party Tools + +If you build a tool that integrates with / makes use of this HDL, feel free to open an issue to request we add it to a list of such tools. +We may review such tools for quality and readiness before listing. + +We are also open to collaborating and discussing on how we can better support third party tooling, particularly community-driven open-source projects. + + +## Example Boards + +Third party designs should go in their own repositories, unless you feel it makes sense as an integration test here. + +We may link high quality example / built-with designs. +Feel free to open an issue or PR. diff --git a/README.md b/README.md index 62649af43..9c20c502c 100644 --- a/README.md +++ b/README.md @@ -3,187 +3,198 @@ ![](https://github.com/BerkeleyHCI/PolymorphicBlocks/actions/workflows/pr-python.yml/badge.svg?branch=master) ![](https://github.com/BerkeleyHCI/PolymorphicBlocks/actions/workflows/pr-scala.yml/badge.svg?branch=master) ![](https://img.shields.io/github/license/BerkeleyHCI/PolymorphicBlocks.svg) -![Python](https://img.shields.io/badge/python-3.9-blue.svg) +![Python](https://img.shields.io/badge/python-3.10--3.13-blue.svg?logo=python&logoColor=white) +_subcircuit generator library based hardware description language for circuit board design_ -Polymorphic Blocks is an open-source, Python-based [hardware description language (HDL)](https://en.wikipedia.org/wiki/Hardware_description_language) for [printed circuit boards (PCBs)](https://en.wikipedia.org/wiki/Printed_circuit_board). -By making use of programming concepts and capabilities, this project aims to **make circuit design faster and easier through high-level subcircuit library blocks** much like what makes software development so productive and approachable. -Underlying language features enable these libraries to be general across many applications and provide a high degree of design automation. +Polymorphic Blocks is an open-source, Python-based [hardware description language (HDL)](https://en.wikipedia.org/wiki/Hardware_description_language) for schematic-equivalent design of printed circuit boards (PCBs). +Its library of components provide a high-level abstraction for circuit design while subcircuit generators automate the calculation of fine details. +Abstract component interfaces enable these libraries to be general across applications and component vendors. -We've been using this system to create a variety of boards of varying complexity, [examples](#examples) range from a charlieplexed LED matrix to a USB source-measure unit. +Generates stable KiCad netlists to be routed in the KiCad PCB Editor. -### A Keyboard Example -An example of all this in action is this design for a USB keyboard with a 3x2 switch matrix: +### Built Boards - - - - - +Many boards have been built with this system, from a mechanical keyboard macropad, to battery-powered IoT devices, to a USB source-measure unit. +Check out the [examples page](examples.md)! - - - - -
User inputWhat this tool does
-The board is defined using high-level library subcircuits blocks, including parameterized ones like the switch matrix. -Choices for internal components can also be specified as refinements, for example generic switches (used in the switch matrix) are refined to Kailh mechanical keyswitch sockets. +## Example: from HDL to Keyboard + +**Overall flow**: write HDL -> generate netlist -> import into KiCad PCB editor -> place and route (optionally iterating with HDL) -> export BoM and Gerbers -> optionally generate JLC PCBA data + +A simplified version of the [getting started tutorial](getting-started.md) is this snippet for a 3x4 mechanical keyboard: ```python +from edg import * + class Keyboard(SimpleBoardTop): - def contents(self) -> None: - super().contents() + def contents(self) -> None: + super().contents() - self.usb = self.Block(UsbCReceptacle()) - self.reg = self.Block(Ldl1117(3.3*Volt(tol=0.05))) - self.connect(self.usb.gnd, self.reg.gnd) - self.connect(self.usb.pwr, self.reg.pwr_in) + self.usb = self.Block(UsbCReceptacle()) + self.reg = self.Block(LinearRegulator(3.3 * Volt(tol=0.05))) + self.connect(self.usb.gnd, self.reg.gnd) + self.connect(self.usb.pwr, self.reg.pwr_in) - with self.implicit_connect( + with self.implicit_connect( ImplicitConnect(self.reg.pwr_out, [Power]), ImplicitConnect(self.reg.gnd, [Common]), - ) as imp: - self.mcu = imp.Block(Stm32f103()) - self.connect(self.usb.usb, self.mcu.usb.request()) - - self.sw = self.Block(SwitchMatrix(nrows=3, ncols=2)) - self.connect(self.sw.cols, self.mcu.gpio.request_vector()) - self.connect(self.sw.rows, self.mcu.gpio.request_vector()) - - def refinements(self) -> Refinements: - return super().refinements() + Refinements( - class_refinements=[ - (Switch, KailhSocket), - ], - ) + ) as imp: + self.mcu = imp.Block(IoController()) + self.connect(self.usb.usb, self.mcu.usb.request()) + + self.sw = self.Block(SwitchMatrix(ncols=3, nrows=4)) + self.connect(self.sw.cols, self.mcu.gpio.request_vector("sw_col")) + self.connect(self.sw.rows, self.mcu.gpio.request_vector("sw_row")) + + self.enc = imp.Block(DigitalRotaryEncoder()) + self.connect(self.enc.a, self.mcu.gpio.request("enc_a")) + self.connect(self.enc.b, self.mcu.gpio.request("enc_b")) + self.connect(self.enc.with_mixin(DigitalRotaryEncoderSwitch()).sw, self.mcu.gpio.request("enc_sw")) + + def refinements(self) -> Refinements: + return super().refinements() + Refinements( + class_refinements=[ + (IoController, Ch32v203), + (Switch, KailhSocket), + ]) + +compile_board_inplace(Keyboard) ``` -These library blocks contain logic to adjust the subcircuit based on how it is used or its parameters. -For example, the USB-C port generates the required CC pulldown resistors if a power delivery controller is not attached, and the STM32 generates the required crystal oscillator if USB is used. -This helps eliminate gotchas for the system designer and makes the overall board more correct-by-construction. +The system: +- provides a library of subcircuit generators, like switch matrices and USB-C ports, that automatically include supporting components like decoupling capacitors and pullup resistors +- automatically selects generic parts like resistors and diodes against builtin parts tables +- performs basic electrical checks on the design, including voltage and current limits, automating some common datasheet parameter checking +- runs fully locally - +This generates: +- a netlist that can be imported into the KiCad PCB editor + - ... including hierarchical data, allowing subcircuit replication / channelization + - ... and have stable tstamps, allowing incremental updates to in-progress board layouts +- a JLCPCB-compatible BoM + - including a [postprocessing script](edg/tools/jlc_pcba/__main__.py) to shift part rotations from KiCad-generated component placements for JLC PCBA +- a [JSON representation of the full design](edg/core/CompiledDesignExport.py), including connectivity and solved circuit values, to integrate with custom / third-party tooling -Compiling the design produces a netlist that can be imported into KiCad for board layout and ultimately Gerber generation for manufacturing: -![](docs/keyboard.png) -_Placement and routing are out of scope of this project, components were manually placed._ +![macropad.webp](docs/boards/macropad.webp) -Additionally, the compiler... -- generates stable netlists, allowing incremental updates to in-progress board layouts -- checks electrical properties like voltage and current limits -- automatically selects generic parts like resistors and diodes against a parts table -- generates a BoM for factory assembly +Advanced capabilities include: +- multi-board support including connector-pair management +- cross-hierarchy packing of multi-pack devices like dual op-amps and quad resistors +- standard abstract component interfaces, allowing for custom implementations of parts like resistors (including from a parts table), and microcontrollers +- full support for user component definition; very little is hard-coded into the infrastructure -
-### Under the Hood +## Getting Started +See the [setup documentation](setup.md), then work through building a mechanical keyboard (including subcircuit layout replication) in the [getting started tutorial](getting-started.md). -While degrees of library-based design are possible in graphical schematic tools, either informally with copy-paste or with hierarchical sheets, the main limitation is that these subcircuits are static and tuned for one particular application. -Baked-in choices like component values, footprint, and part number selection may not meet requirements for a different application that might, for example, call for through-hole components instead of surface-mount, or has different voltage rails. +**Setup tl;dr**: install from pip, published as `edg`: `pip install edg`. +You will need a Java 11+ JRE / JDK, to run the Scala-based core compiler. -The HDL provides two mechanisms to enable general subcircuit libraries: _generators_ and _abstract parts_. -Defining the subcircuit as code enables the library to contain logic to _generate_ the implementation to support many applications. -For instance, instead of a keyboard switch matrix with a fixed number of rows and columns, the library can take in user-specified `nrows` and `ncols` parameters and generate the matrix for that configuration. -A more complex example would be a buck converter generator, which automatically sizes its inductor and capacitors based on the current draw of connected components. +Also check out the [reference documentation](reference.md) for a concise list of capabilities. -While generators enable the subcircuit to adapt to its environment, _abstract parts_ formalize and automate the concept of generic parts within subcircuits. -Instead of requiring baked in part numbers and footprints in subcircuits, library builders can instead place an abstract part like generic resistors, generic diodes, and even generic microcontrollers. -These only define the parts' interface but have no implementation; instead other library blocks can implement (subtype) the interface. -For example, the abstract interface can be implemented by a SMT resistor generator, a through-hole resistor generator, or a resistor that picks from a vendor part table. -_Refinements_ allow the system designer to choose how parts are replaced with subtypes. +Some documentation is available for library parts construction. +Be warned, this is more complex and less polished. +See the [library block definition tutorial using KiCad schematic import](getting_started_schimport.md) and the [library construction reference](reference_library.md). -An _electronics model_ performs basic checks on the design, including voltage limits, current limits, and signal level compatibility. -Advanced features like cross-hierarchy packing allows the use of multipack devices, like dual-pack op-amps and quad-pack resistors to optimize for space and cost. +## Compared to Hierarchical Schematics -## Getting Started -See the [setup documentation](setup.md), then work through building a blinky board in the [getting started tutorial](getting-started.md). +The main goal of this HDL is to enable the creation of _general_ subcircuit libraries that can be reused across many applications. + +While graphical schematic tools support hierarchical sheets, direct re-use is limited because the sheets encode a lot of per-design information, like a specific resistor values or footprints. +Different users may have different requirements (e.g., different resistor values for a LED based on its input voltage, or preference for through-hole vs. surface-mount components). + +This HDL addresses those limitations with two mechanisms: +- **Generators** allow the implementation of the subcircuit to depend on high-level parameters. + A LED circuit could automatically size its resistor based on the input voltage. +- **Abstract parts** allow the subcircuit to use generic parts with generic interfaces, which many parts can implement. + An abstract resistor interface could be implemented by through-hole and surface-mount resistors, enabling a generic LED circuit and deferring the choice. + The top-level designer can then specify _refinements_ to make the specific choice of parts. -**Setup tl;dr**: install the Python package from pip: `pip install edg`, and optionally run the [IDE plugin with block diagram visualizer](setup.md#ide-setup). +Both of these combined also present a higher level of abstraction for the board designer, more at the system architecture level-of-design than schematics. +We suspect this will also make it easier for novices to design boards, reducing the knowledge barrier to entry. -Building from source: `pip install .` at the repository root. +### Graphical Tooling + +The fundamental design structure is the hierarchical block diagram, and we expect graphical tooling can layer cleanly on top of the HDL core. +Our current focus is on the HDL core and parts libraries, but we are open to collaborations with those interested in building graphical tooling. +We suspect this may be particularly useful for novice users. + +We built a proof-of-concept mixed textual / graphical [IDE plugin for IntelliJ / PyCharm](https://github.com/BerkeleyHCI/edg-ide). +It has some nifty concepts (including [design space sweep](https://doi.org/10.1145/3613904.3642009)) but is rough around the edges and only sees basic maintenance. +It could be a good source for ideas for community developers. ## Additional Notes -### Examples -Example boards, including layouts, are available in the [examples/](examples/) directory, structured as unit tests and including board layouts: +### Project Status +**This is functional has been used to [produce a wide variety of boards](examples.md) over the years.** +While the core is reasonably stable, as a pre-v1.0-release there are no formal guarantees of API stability. +In practice, deprecation shims are / will be maintained for common features if APIs change. + +This started as an academic research project and continues to be developed as a personal project post-graduation, including for designing boards for fun. + +### (Some) Dragons Be Ahead +Many functional boards have been built with this system and most of the library parts have been physically tested (some across many designs), but there may still be bugs and edge cases. +You are recommended to sanity check generated designs during layout. - - - - - +ESPHome boards are a great fit. - - - - +This system has a concept of parameters (variables, think voltages and currents) that can be attached to blocks and propagate through ports. +This is limited to directed assignments, with the goal of deterministic, predictable compilation. - - - - +Most passive parts / discretes are selected from a 2022 JLCPCB parts table (included in this repository). +JLC no longer makes parts tables publicly available. -
- +Be prepared for things to be rough around the edges. +The error messages in particular are not great and need work. -**[LED Matrix](examples/test_ledmatrix.py)**: a 6x5 LED matrix using a [charlieplexed](https://en.wikipedia.org/wiki/Charlieplexing) circuit generator that drives 30 LEDs off of just 7 IO pins. +Building boards with the included libraries should be relatively straightforward, but building custom library parts is a more complex process. - - +### Scope +The current libraries best support intermediate-level (and simpler) PCB designs. +This includes circuits with discrete microcontrollers, microcontroller modules (like ESP32s), and socketed dev boards. +Libraries include common subcircuits like switch matrices, digitally attached peripherals like I2C sensors, voltage converters, and some analog signal conditioning circuits. +Check out the [subcircuits library folder](edg/circuits/) and [parts library folder](edg/parts/). -[Simon](examples/test_simon.py): a [Simon memory game](https://en.wikipedia.org/wiki/Simon_(game)) implementation with a speaker and [12v illuminated dome buttons](https://www.sparkfun.com/products/9181). +There is no prescribed architecture and microcontrollers are not required. -
- +Designs that do not decompose neatly(ish) into subcircuits blocks are a poor fit. -**[IoT Fan Driver](examples/test_iot_fan.py)**: an [ESPHome](https://esphome.io/index.html)-based internet-of-things fan controller, controlling and monitoring up to two computer fans from a web page or [home automation dashboard](https://www.home-assistant.io/). +There is no support for high-speed digital design (like DDR memories). +There are some experimental RF subcircuits. - - +The electrical checks are not a design assurance tool and only automate some of the most common datasheet checks. +More advanced parameters, especially performance characteristics not related to maximum ratings, are currently out of scope of the electronics model. -**[CAN Adapter](examples/test_can_adapter.py)**: an isolated [CANbus](https://en.wikipedia.org/wiki/CAN_bus) to USB-C adapter. +### Parameter Engine -
- +Assertions are supported on parameters to enforce electrical correctness checks. -**[BLE Multimeter](examples/test_multimeter.py)**: a BLE (Bluetooth Low Energy) compact (stick form factor) multimeter, supporting volts / ohms / diode / continuity test mode, for low voltage applications. +Solving may happen within a single block with arbitrary Python code (for example, find the best set of E12 resistor values to implement a divider), but not across multiple blocks. +Search involving multiple blocks must be handled by the block exposing tuning knobs and the user turning those knobs with recompilation. - - -**[USB Source-Measure Unit](examples/test_usb_source_measure.py)**: a USB PD (type-C power delivery) source-measure unit -- which can both act as a DC power supply with configurable voltage and current, and as a DC load. More precisely, it's a digitally-controlled 2-quadrant (positive voltage, positive or negative current) power source. +### Parts Data -
+This parts table still works well and boards have been built using this table as recently as 2026. +Some basic parts have drifted and some parts may be no longer stocked. -### Developing -**If you're interested in collaborating or contributing, please reach out to us**, and we do take pull requests. -Ultimately, we'd like to see an open-source PCB HDL that increases design automation, reduces tedious work, and makes electronics more accessible to everyone. +### Contributing +We take pull requests and would love to see contributions and collaborations! -See [developing.md](developing.md) for developer documentation. +See [CONTRIBUTING.md](CONTRIBUTING.md) for details. ### Papers This started as an academic project, though with the goal of broader adoption. Check out our papers (all open-access), which have more details: -- [System overview, UIST'20](http://dx.doi.org/10.1145/3379337.3415860) +- [System overview, UIST'20](http://dx.doi.org/10.1145/3379337.3415860) (some details may be out of date) - [Mixed block-diagram / textual code IDE, UIST'21](https://dl.acm.org/doi/10.1145/3472749.3474804) - [Array ports and multi-packed devices, SCF'22](https://doi.org/10.1145/3559400.3561997) - -### Project Status and Scope -**This is functional and produces boards, but is still a continuing work-in-progress.** -APIs and libraries may continue to change, though the core has largely stabilized. - -If you're looking for a mature PCB design tool that just works, this currently isn't it (yet). -For a mature and open-source graphical schematic capture and board layout tool, check out [KiCad](https://kicad-pcb.org/), though existing design tools generally have nowhere near the design automation capabilities our system provides. -**However, if you are interested in trying something new, we're happy to help you and answer questions.** - -Current development focuses on supporting intermediate-level PCB projects, like those an advanced hobbyist would make. -Typical systems would involve power conditioning circuits, a microcontroller, and supporting peripherals (possibly including analog blocks). -There is no hard-coded architecture (a microcontroller is not needed), and pure analog boards are possible. -The system should also be able to handle projects that are much more or much less complex, especially if supporting libraries exist. +- [Design space sweep / exploration, CHI'24](https://doi.org/10.1145/3613904.3642009) ### Misc - **_What is EDG?_**: diff --git a/developing.md b/developing.md index d520cbd0f..0a10d141a 100644 --- a/developing.md +++ b/developing.md @@ -1,16 +1,5 @@ # Developer Documentation - -## Overview -This project consists of two (and a half) major parts: -- The frontend (user-facing) HDL, written in Python, living in the top-level folders like `edg_core/`. - This _elaborates_ user-written HDL into an internal hierarchical block-diagram representation on a block-by-block, single-level-deep basis. - - This also includes the electronics model and libraries build atop the core, in `electronics_model/`, `electronics_abstract_parts/`, and `electronics_lib/`. -- The compiler, written in Scala, living in `compiler/`. - This _compiles_ together a whole design, starting at the top-level block and dropping in sub-blocks (recursively), invoking generators, and resolving parameters. -- The intermediate representation (defining the core hierarchical block diagram model - blocks, ports, links, and expressions - in a language-independent form), written in protobuf, living in `proto/`. - - ## Quick Reference Commands ### Static checking @@ -28,9 +17,6 @@ dmypy run . Or, using the [Mypy plugin for Intellij](https://plugins.jetbrains.com/plugin/13348-mypy-official-). -Note: since mypy currently doesn't infer return types (see mypy issue 4409), some defs might be incomplete, so the type check is leaky and we can't currently use `--disallow-incomplete-defs` or `--disallow-untyped-defs`. -If that doesn't get resolved, we might go through and manually annotate all return types. - ### Unit testing ``` python -m unittest discover @@ -47,8 +33,6 @@ python -m unittest examples.test_blinky.BlinkyTestCase.test_design_complete ``` -**PROTIP**: run both static type checking and unit testing by combining the commands with `&&` - ### Compiling the Compiler A pre-compiled compiler JAR is included. If you have not modified any of the .scala files, you do not need to recompile the compiler. @@ -57,80 +41,3 @@ If you have not modified any of the .scala files, you do not need to recompile t 2. In the `compiler/` folder, run `sbt assembly` to compile the compiler JAR file. The system will automatically prefer the locally built JAR file over the pre-compiled JAR and indicate its use through the console. 3. Optionally, to commit a new pre-compiled JAR, move the newly compiled JAR from `compiler/target/scala-*/edg-compiler-assembly-*-SNAPSHOT.jar` to `edg_core/resources/edg-compiler-precompiled.jar`. - -### Packaging -Largely based on [this tutorial](https://realpython.com/pypi-publish-python-package/). - -Local: -- Install in editable mode (package refers to this source directory, instead of making a copy): `python -m pip install -e .` - -Upload: -- These dependencies are necessary: `python -m pip install build twine` -- Build the package (creates a `dist` folder with a `.whl` (zipped) file): `python -m build` -- Optionally, upload to TestPyPI: `python -m twine upload -r testpypi dist/*` -- Upload to PyPI: `python -m twine upload dist/*` - - -## Frontend Architecture -_Some documentation may be out of date._ - -### Core -`edg_core` is the core package, and sets up base classes for the hierarchy block and links model. -These are domain-neutral (not specific to circuit boards, or even electronics). -The Python implementation of the compiler (backend) also lives here. - -#### Block Diagram -- BaseBlock: abstract base class for all block-like constructs, which contain ports (IOs), parameters, and constraints between them. - In general, subclasses may override superclass ports with a subtype port. (TODO: is this a good idea?) - Provides infrastructure to record the names of ports and parameters (by overriding __setattr__) with the syntax self.[name] = self.Port([port]) -- Link: abstract base class for all links, which are inferred to fit a connection between ports. -- Block: abstract base class for blocks. -- ConcreteBlock: abstract base class for blocks that can be part of a final design. -- PortBridge: block-like construct that defines how an external port of a hierarchy block connects to an internal link, such as by adapting the type and propagating constraints. -- HierarchyBlock: abstract base class for blocks that contain an internal block diagram (with internal blocks and connections), which may also link to external ports. -- GeneratorPart (TODO: needs renaming and implementation): a hierarchy block that contains a function to generate the internal block diagram once the external block diagram is solved. - Allows arbitrary Python to control the internal generation, since it is not part of the SMT loop. -- BasePort: abstract mixin for all port-like constructs, which knows its parent (either a block or a container port). -- BaseContainerPort: abstract base class for all ports that contains other ports. -- Port: abstract base class for leaf-level ports, which contains parameters. - Defines the link_type it may connect to (TODO: should it support multiple link types, of a common superclass?), and provides access to the connected link which can be used to avoid propagating duplicate parameters. - Also defines the bridge_type, if one exists where this port is the external port on a hierarchy block. -- Bundle: a Port and a BaseContainerPort, that defines internal fields (other ports). -- Vector: an unknown-sized vector (array) of ports, which supports a map-extract operation to return an Array of some inner parameter as well as reduction operators that wrap the map-extract and an Array reduction. - -#### Parameters & Expressions -- ConstraintExpr: abstract base class for constraint expressions. -- BoolExpr: ConstraintExpr that is a Bool. -- NumLikeExpr: ConstraintExpr abstract base class for numeric expressions, provides arithmetic operations compatible with SMT solvers (add, subtract, comparison). -- FloatExpr: ConstraintExpr that is a real number. -- RangeExpr: ConstraintExpr that is a real-valued interval type, with a min and max. (TODO: may support null-intervals) -- Array: an unknown-sized array (container) of ConstraintExpr, which supports reduction operators (eg, sum, min, max, intersection). - -#### Other -- Driver: provides auto-discovery of block diagram components in a Python library. - (TODO: provides conversion to design, including recursive instantiation of library elements) - -#### Intermediate Representation -The fundamental hierarchy blocks and links model is encoded as an [intermediate representation](https://en.wikipedia.org/wiki/Intermediate_representation) in [Protocol Buffer](https://developers.google.com/protocol-buffers), -The Protocol Buffers schema is in the [edgir](edgir) folder, and generated Protocol Buffers code (including Python type annotations) is committed to this repository. -The intent behind this is to allow cross-language interoperability (eg, solver implemented in another, more efficient, language) and to define a compiled object format. - -You can ignore this section, unless you are changing the Protocol Buffer structure. - -### Electronics Model -`electronics_model` uses the `edg_core` classes to define an electronics model, by adding base classes to support circuit design (pin ports, copper-net links, and footprint blocks) and defining common electronics types. - -- VoltageSink/Source/Link/Bridge: represents a single copper net, and models runtime voltage and currents as well as their limits - Can be used as a base class for other single-copper-net ports. -- DigitalSink/Source/Link/Bridge: subclass of Voltage*, additionally models logic IO thresholds -- BaseCircuitBlock: a Block with associated footprints (where pins can be mapped to Voltage* ports) and nets (connections between Voltage* ports) - This can be used for component-level blocks, links (with nets defining copper connectivity between ports), and hierarchy blocks. - Not all blocks need a footprint: abstract blocks can rely on a refinement for a footprint, and hierarchy blocks can rely on internal blocks for footprints. - -`electronics_abstract_parts` further defines abstract block types for the type hierarchy of components. - -### Standard Parts -`electronics_lib` contains a standard library of actual parts (eg, could buy off DigiKey), their models, and supporting reference implementation components / circuits. - -### Examples -`examples` contains several example top-level boards, written as test cases and run with the unit test suite. diff --git a/docs/boards/UsbSmuControl.png b/docs/boards/UsbSmuControl.png new file mode 100644 index 000000000..83bc23f69 Binary files /dev/null and b/docs/boards/UsbSmuControl.png differ diff --git a/docs/boards/blejoystick_combined.webp b/docs/boards/blejoystick_combined.webp new file mode 100644 index 000000000..65aad2b71 Binary files /dev/null and b/docs/boards/blejoystick_combined.webp differ diff --git a/docs/boards/candapter.webp b/docs/boards/candapter.webp deleted file mode 100644 index 5757486fb..000000000 Binary files a/docs/boards/candapter.webp and /dev/null differ diff --git a/docs/boards/debuggers.webp b/docs/boards/debuggers.webp new file mode 100644 index 000000000..67ebf2869 Binary files /dev/null and b/docs/boards/debuggers.webp differ diff --git a/docs/boards/eink_assembly.webp b/docs/boards/eink_assembly.webp new file mode 100644 index 000000000..7e9677d3f Binary files /dev/null and b/docs/boards/eink_assembly.webp differ diff --git a/docs/boards/esp_lora.webp b/docs/boards/esp_lora.webp new file mode 100644 index 000000000..ce9487474 Binary files /dev/null and b/docs/boards/esp_lora.webp differ diff --git a/docs/boards/fcml.webp b/docs/boards/fcml.webp new file mode 100644 index 000000000..8ae34deaf Binary files /dev/null and b/docs/boards/fcml.webp differ diff --git a/docs/boards/ledmatrix.webp b/docs/boards/ledmatrix.webp deleted file mode 100644 index a4ee658ae..000000000 Binary files a/docs/boards/ledmatrix.webp and /dev/null differ diff --git a/docs/boards/macropad.webp b/docs/boards/macropad.webp new file mode 100644 index 000000000..6da0bd187 Binary files /dev/null and b/docs/boards/macropad.webp differ diff --git a/docs/boards/simon.webp b/docs/boards/simon.webp deleted file mode 100644 index 6068c6595..000000000 Binary files a/docs/boards/simon.webp and /dev/null differ diff --git a/docs/boards/usb_smu.webp b/docs/boards/usb_smu.webp index c5f9a5055..a281a9c76 100644 Binary files a/docs/boards/usb_smu.webp and b/docs/boards/usb_smu.webp differ diff --git a/examples.md b/examples.md new file mode 100644 index 000000000..8a4d68737 --- /dev/null +++ b/examples.md @@ -0,0 +1,106 @@ +# Example boards + +This is a small, curated list of example boards built with this HDL framework. + + +## Mechanical Macropad + +![macropad.webp](docs/boards/macropad.webp) + +[test_keyboard.py](examples/test_keyboard.py), [Keyboard.kicad_pcb](examples/Keyboard/Keyboard.kicad_pcb) + +[Minimal Rust firmware](https://github.com/ducky64/edg-pcbs/tree/main/KeyboardExample) (note, RMK crashes on this device, possibly an issue with mutex implementation on the CH32V203 HAL). + +A 3x4 mechanical macropad with per-key RGB lighting, using a discrete CH32V203 microcontroller and USB-C. +Also includes a rotary encoder and a small OLED display. +Example of a full device built with minimal HDL, demonstrating the power of subcircuit generator libraries. + +A variation of the design in the [getting started tutorial](getting-started.md). + + +## BLE Joystick + +_This is a new board, bring-up is a work in progress._ + +![blejoystick_combined.webp](docs/boards/blejoystick_combined.webp) + +[test_ble_joystick.py](examples/test_ble_joystick.py), [BleJoystick.kicad_pcb](examples/BleJoystick/BleJoystick.kicad_pcb) (main board), [BleJoystick_btns.kicad_pcb](examples/BleJoystick/BleJoystick_btns.kicad_pcb) (buttons sub-board), [BleJoystick_stick.kicad_pcb](examples/BleJoystick/BleJoystick_stick.kicad_pcb) (joystick FPC) + +[Rust firmware](https://github.com/ducky64/blejoystick-rs) + +An nRF52840 based air-mouse with an XBox joystick and d-pad. + +Example of a three board assembly with connector-pairs managed by the system: the buttons daughterboard connects to the main board via a FFC, and the joystick itself is on a FPC "board". + + +## USB Source-Measure + +![usb_smu.webp](docs/boards/usb_smu.webp) + +[test_usb_source_measure.py](examples/test_usb_source_measure.py), [UsbSourceMeasure.kicad_pcb](examples/UsbSourceMeasure/UsbSourceMeasure.kicad_pcb) + +[ESPHome firmware](https://github.com/ducky64/usb-source-measure/) + +A portable 2-quadrant (positive voltage only, sourcing or sinking current) DC power supply, powered from USB-PD. +Design target of 0 - 30V output, -3 - +3A current (electrical limits, thermal limits lower), three current ranges (30mA, 300mA, 3A). +Buck-boost (four-switch) pre-regulator and linear analog feedback stage. + +Example of a fairly complex device with dual-pack opamps and significant analog circuitry. +The analog feedback circuitry is a high-level KiCad-schematic-defined-block: + +![UsbSmuControl.png](docs/boards/UsbSmuControl.png) + +This device functions fine as a basic DC lab supply but frequency response and measurement noise needs more tuning and iteration. + + +## E-ink Display + +![eink_assembly.webp](docs/boards/eink_assembly.webp) + +[test_iot_display.py](examples/test_iot_display.py), [IotDisplay.kicad_pcb](examples/IotDisplay/IotDisplay.kicad_pcb) + +[Arduino firmware](https://github.com/ducky64/edg-pcbs/tree/main/IoTDisplay) + +A battery-powered WiFi e-ink display controller with low sleep current and expected 1 year life on 4xAA batteries. +Designed for simple deployment: no power wires to run, piggybacks off existing WiFi network infrastructure. + +A few of these are deployed outside the UCLA ECE departmental meeting rooms as room calendars. + + +## SWD and ESP Programmers + +![debuggers.webp](docs/boards/debuggers.webp) + +[test_swd_debugger.py](examples/test_swd_debugger.py), [SwdDebugger.kicad_pcb](examples/SwdDebugger.kicad_pcb), [PicoProbe.kicad_pcb](examples/PicoProbe/PicoProbe.kicad_pcb), + +[test_esp_programmer.py](examples/test_esp_programmer.py), [EspProgrammer.kicad_pcb](examples/EspProgrammer/EspProgrammer.kicad_pcb) + +Tiny SWD and ESP programmers with USB-C and a 6-pin Tag-Connect interface to the target. + +The STM32 SWD programmer run a variation of [DAPLink](https://github.com/armmbed/daplink), the RP2040 SWD programmer runs the Picoprobe firmware. + +The ESP programmer is a CP2102 USB-UART bridge with no microcontroller. + + +## LoRa and NFC Demonstrator + +![esp_lora.webp](docs/boards/esp_lora.webp) + +[test_lora.py](examples/test_lora.py), [EspLora.kicad_pcb](examples/EspLora/EspLora.kicad_pcb) + +[ESPHome firmware for NFC](https://github.com/ducky64/edg-pcbs/blob/main/IoTDevices/nfctest.yml); also runs Meshtastic + +A demonstrator / test board for RF subcircuit generators, generating the analog frontend for the SX1262 LoRa transceiver and PN7160 NFC controller. +Both of these subcircuits work, though RF performance hasn't been characterized in any detail. + + +## Multilevel Converter Demonstrator + +![fcml.webp](docs/boards/fcml.webp) + +[test_fcml.py](examples/test_fcml.py), [Fcml.kicad_pcb](examples/Fcml/Fcml.kicad_pcb) + +[Minimal Chisel RTL / gateware](https://github.com/calisco/fcml-rtl) + +A design using an iCE40 FPGA that drives a 4-level flying capacitor multilevel buck converter, a converter topology that trades inductor size for more switches. +A few basic tests have been run with this device, and it appears to be able to process power efficiently.