Polymorphic Blocks is an open-source, Python-based hardware description language (HDL) for printed circuit boards (PCBs). 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.
We've been using this system to create a variety of boards of varying complexity, examples range from a charlieplexed LED matrix to a USB source-measure unit.
An example of all this in action is this design for a USB keyboard with a 3x2 switch matrix:
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.
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.
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.
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.
See the setup documentation, then work through building a blinky board in the getting started tutorial.
Setup tl;dr: install the Python package from pip: pip install edg
, and optionally run the IDE plugin with block diagram visualizer.
Example boards, including layouts, are available in the examples/ directory, structured as unit tests and including board layouts:
LED Matrix: a 6x5 LED matrix using a charlieplexed circuit generator that drives 30 LEDs off of just 7 IO pins. |
Simon: a Simon memory game implementation with a speaker and 12v illuminated dome buttons. |
IoT Fan Driver: an ESPHome-based internet-of-things fan controller, controlling and monitoring up to two computer fans from a web page or home automation dashboard. |
CAN Adapter: an isolated CANbus to USB-C adapter. |
BLE Multimeter: a BLE (Bluetooth Low Energy) compact (stick form factor) multimeter, supporting volts / ohms / diode / continuity test mode, for low voltage applications. |
USB Source-Measure Unit: 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. |
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.
See developing.md for developer documentation.
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
- Mixed block-diagram / textual code IDE, UIST'21
- Array ports and multi-packed devices, SCF'22
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, 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.
- What is EDG?:
Embedded Device Generation (or more generally Electronic Device Generation) was a prior version of this project that focused on algorithms and models for embedded device synthesis, though it lacked a user-facing component.
This project is a continuation of that work focusing on an end-to-end system, and for most of its development cycle has been called
edg
. But, for the purposes of writing research papers, naming collisions are confusing and bad, and we chose to keep the repo and paper name consistent.