An embedded language for describing hydraulic integrated circuits (work-in-progress)
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Washing Machine Design Language

An embedded language for describing hydraulic integrated circuits.


Create group file using high level DSL:

    specify :: python source file -> groups

Take a group file and recursively merge identical groups.
This can probably happen as part of serialisation:

    deduplicate :: groups -> groups

Take a group file and decide how to layout the features in each group.
This can probably be made to take advantage of layouts computed for a previous version.

    place :: target -> groups -> group_layout

Expand a list of groups and corresponding list of layouts into a list of transistors and transistor offsets:

    flatten :: (groups, group_layout) -> (transistors, transistor_layout)

Figure out where to place tracks to join all of the transistors:

    route :: target -> (transistors, transistor_layout) -> routes

Turn the lists of transistors, offsets, and routes into a list of layers:

    reify :: target -> (transistors, transistor_layout, routes) -> [layer]

Render each layer to something usable:

    render_svg :: layer -> svg
    render_openscad :: [layer] -> openscad

Possible models

Reference Types

This is as implemented.  TODO: document.

Value Types

Transistors and Groups:
  - Are value objects
  - Don't know what they are called
  - Don't know where they are used
  - Are public
  - Can be re-used in multiple places.

  - Have no hash until frozen.
  - Cannot be compared until frozen.

Feature objects
  - Never leave their containing group
  - Have an associated name
  - Compare equal to other features with an equal transistor or group AND name.
    This fact is used only for comparing groups.

Connection objects:
  - Never leave their containing group
  - Contain references to features, not groups

File formats


"transistors": [
    {"slots": [[0, 1], [3, 4]],}
"groups": [
        "children": [
            "a": {"type": "transistor", "identifier": 123},
            "b": {"type": "group", "identifier": 81},
        "connections": [
                {"feature": 0, "contact": 2},
                {"feature": 1, "contact": 1},
                {"feature": 0, "contact": 1},
        "contacts": [
            {"name": "A+", "connection": 0}

Layout Hints

TODO: Probably CSS.

Hierarchical layout

A list of lists of relative offsets.
The entries of the outer list correspond to groups.
The entries of the inner lists correspond to children of those groups

"groupLayouts": [
        {"x": 0, "y": 1, "a": 3},


"transistors": {
    {"slots": [[0, 1], [3, 4]],}
    {"slots": [[0, 1], [3, 4]],}
    {"slots": [[0, 1], [3, 4]],}

Flattened Layout

"transistorLayouts": [
    {"x": 0, "y": 1, "a": 3},

Three lists of nodes, one for each direction, saying which points should be linked to the next point in that direction.



[ ] Correspondence between gate properties, fluid properties, and losses
[ ] Correspondence between tube length, tube radius, fluid properties, and flow rate

[ ] Test tubing to connector fit
[ ] Test mylar thickness to ease of movement
[ ] Test if it's possible to use pistons cut from cylinders
[ ] Test cut acrylic on cut acrylic

[x] NAND gate
[ ] Tee
[ ] Symmetrical XOR gate with gain
[ ] Half adder
[ ] Full adder




[ ] Render a nand gate to SVG
    [x] Get nand gate builder function to run from beginning to end
    [x] Render pins
    [x] Calculate transistor contact locations
    [x] Basic horizontal routing
    [x] Render overlapping routes
    [x] Render routes properly using half-edge tracing
    [ ] Render transistors
    [ ] Render bounds and mounting holds
    [ ] Render outputs
    [ ] Split rendering human view, and outputting laser cutter file
[x] Generate a net list of a nand gate
[x] Replace layer types with single layer that supports all primitive features
[x] Separate routing from placement
[ ] Create circuit datastructure
    [x] Create table of transistor contacts and table of group contacts.
    [x] Merge ...FeatureIds and ...Ids and convert FeatureId to a union.
    [x] Remove all placement logic.
    [ ] Add mechanism for labeling features and contacts.
[ ] Placement
    [x] Decide on representation for placement output
    [x] Implement manual placement using a hints file.
    [ ] Create placement API that takes
    [ ] Implement very simple automatic placement that just puts things next to
        each other on a single layer.
    [ ] Add mechanism for describing output constraints such as the size of the
        area the placement algorithm can work in and the spacing of transistor
[ ] Routing
    [ ] Implement simple routing, in python, using A*.
    [ ] Implement track tearing, or some other mechanism to get out of binds.

[ ] Figure out how to represent thick tubes and big transistors
[ ] Automatic merging of switches within a feature into compound transistors
[ ] Add svg vector type

Feature Tree

Contact identifiers:
  - Feature, contact name.
  - Feature id, contact name.
  - Composite feature, feature id, contact name.
  - Unique identifier that can be looked up in the circuit.

  - New stateful feature instance per node
  - Single stateless feature instance shared between nodes
  - No tree, transistors are added to a data-structure that defines constraints
    at a different level or doesn't define constraints at all
  - No tree, features are converted into a list of transistors and routes when
    a feature is frozen.

  - Need to define routes before doing placement
  - Need to figure out placement the children of a node before it, in turn, can
    be placed

  - Create a new feature builder instance
  - Add feature
  - Add feature
  - Call freeze
      - Place child features
      - Extract transistors from child feature
      - Convert routes in child feature to routes in feature

      - Child writes its transistors
      - Child writes its routes
      - We somehow convert our routes from routes connecting child contacts to
        routes connecting our own contacts

  - A feature
  - A map from a set of labeled input and output ports

  - A set of positioned transistors
  - A map from semantic identifiers to sets of transistor pin identifiers

  - Feature
  - Pin
  - Connection
  - Route
  - Transistor
  - Layer

x and y coordinates are just positive integers.
They are generally passed to functions as an (x, y) tuple (TODO)

Power rails
Power rails need to go from one end of the circuit to the other

  - Put power rails underneath the circuit in a fixed position.
    This requires that we get lucky and that all basic gates can be built with
    the rail in the same place.
    This has the advantage that it may make analysing the netlist easier
  - Put power rails on the transistor layer and pick them up from the layer above
    This is just irritating.


layers are stacked in a top to bottom linked list which allows users to get a
Layer interface handle to the layer below.

To get layers of a specific type they must be unpacked from a tuple in the
circuit object.

Layer sets

  - Should the netlist be represented as a heirarchy?
  - How should manual hints be passed to the placement and routing parts

Possible approaches:
  - Manual placement + semi-automatic routing with validation to check that design matches model.  Build useful netlist diff tool

rendering algorithm to get nice clean paths in SVG
  - Each route has two sides
  - Create list of the sides of routes that need to be rendered.
  - While the list of sides is not empty
      - Pick and remove a random side from the list
      - Trace a path in one direction from the starting side removing them in turn until you reach the starting side
  - There shouldn't be any encircled edges so it shouldn't matter what order the sides are cut in.

Storing routes:
  - Individual multi-segment paths
  - set of links

  - adjacency list with a single entry per route
  - adjacency list with entries for both forwards and backwards
  - sets of nodes with an route in a particular direction (and a set of nodes that contains pins)



Purpose-made Tube fittings

Piping suitable for ad-hoc tube fittings

Laser cutting services

Working fluids

Instruction Set


4 bit opcode, 8 bit operand