Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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.
257 changes: 134 additions & 123 deletions README.md

Large diffs are not rendered by default.

93 changes: 0 additions & 93 deletions developing.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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.
Binary file added docs/boards/UsbSmuControl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/boards/blejoystick_combined.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/boards/candapter.webp
Binary file not shown.
Binary file added docs/boards/debuggers.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/boards/eink_assembly.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/boards/esp_lora.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/boards/fcml.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/boards/ledmatrix.webp
Binary file not shown.
Binary file added docs/boards/macropad.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/boards/simon.webp
Binary file not shown.
Binary file modified docs/boards/usb_smu.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 106 additions & 0 deletions examples.md
Original file line number Diff line number Diff line change
@@ -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.