Could you imagine the pain of building an entire software product using only assembly code? That’s about how we felt designing hardware. We don’t currently have good ways to describe what we need, reuse existing designs and compile that description down to a product.
We started atopile to fix this. atopile is an open-source language and toolchain to describe circuits with code. The compiler is here: https://github.com/atopile/atopile Docs are here: https://atopile.io/getting-started/ . For a detailed deep dive designing an ESP32 module, see this video: https://youtu.be/eMWRwZOajdQ
We realized this was a problem in our previous jobs. Narayan and I (Tim) had to manually, draw and export all our electronic circuit boards. This lasted until our friend Matt, a software engineer, showed us his development workflow. All his projects were built, tested, and merged automatically via GitHub. So we asked: Can we build the same for hardware?
We observed that the ability to abstract electronics effectively hinged on using a language to describe the requirements, so we came up with the “ato” language. In ato, you can break down circuits into modules, components and interfaces. You can nest and connect those blocks with each other. Here is an example with an RP2040 microcontroller:
import RP2040Kit from "rp2040/RP2040Kit.ato"
import LEDIndicatorBlue from "generics/leds.ato"
import LDOReg3V3 from "regulators/regulators.ato"
import USBCConn from "usb-connectors/usb-connectors.ato"
module Blinky:
micro_controller = new RP2040Kit
led_indicator = new LEDIndicatorBlue
voltage_regulator = new LDOReg3V3
usb_c_connector = new USBCConn
usb_c_connector.power ~ voltage_regulator.power_in
voltage_regulator.power_out ~ micro_controller.power
micro_controller.gpio13 ~ led_indicator.input
micro_controller.power.gnd ~ led_indicator.gnd
led_indicator.resistor.value = 100ohm +/- 10%
From there, the compiler produces a netlist that describes how the circuit is connected and selects jelly-bean components for you (https://atopile.io/blog/2024/01/31/cloud-components/). Our next focus will be to add layout reuse, mathematical relations between values and define circuits by traits (similar to Rusts’).At the moment, atopile is intended to design all types of printed circuit boards (PCB) with low to medium complexity. The circuit complexity that the compiler can handle will steadily increase until it becomes suited for production usage. We often get asked if the compiler is meant for chip design rather than PCBs, but that is not the case. The language is exclusive to PCBs. At least for now..!
A big part of why the software community is so prolific is thanks to open source and open core technology. The ability to share software packages with each other and efficiently chain tools together has made the software world an awesome place for developers. As hardware engineers, we would love our field to benefit from this as well. That’s why we’ve made atopile’s core open source (Apache 2.0). We plan to generate revenue by selling entreprise targeted features, similar to GitLab.
We would love to have your thoughts on the compiler! What’s your story in electronics? What would you want us to build?
The state of electronics tooling has long been extremely bad - 99% of people who put a regulator into their schematic will want an appropriate input and output capacitor as the datasheet demands. 99% of people who put a microcontroller will want a crystal and a programming port and a reset pin pull-up. It's only because of closed source tools stuck in the stone age that the state of the art is to copy out of a PDF.
And multiple people working on the same design and merging their changes? Forget about it!
It'll be very exciting if we can move towards a more modular world, where designs can be composed.
Not really. KiCad is open-source and a very capable EDA suite, for example.
The problem is that it's a really hard problem for which no one-size-fits-all solution exists. There's basically an infinite number of properties which are important when designing electronics, many of which will have to be nudged depending on your design. Capturing all that in a data format is virtually impossible, and any attempt to do so is likely to degrade into something unusual quite quickly once you get past the trivial stuff.
In my experience reading it out of a PDF is usually not that big of a deal, once you get used to it. For things like schematics symbols and footprints there are data interchange formats available - and there's a pretty decent chance these days they'll be openly available for the part you are using. But they always contain mistakes, and I find it way faster to just roll my own from the PDF than to copy it ready-made from a 3rd party and fix the errors.
Not really, IME.
Let's say I want a SMPS. Something basic, say 12-24v in 3.3v out at 1A. I can buy a module and solder it onto my PCB, or copy a reference design out of a PDF, or vendors like TI have tools like webbench to help me generate a custom design.
The vendor wants to hand me a proven design and have me buy their chips. I want to be handed a proven design and know my project's going to work right first time. But no, the likes of Altium have got to have their vendor lock-in by making copy-and-paste absolutely as difficult as possible.
There's no great skill or inventiveness in me drawing out the world's billionth SMPS design. I'm not "solving a hard problem" - it's drudgery.
> and there's a pretty decent chance these days they'll be openly available for the part you are using. But they always contain mistakes,
So you'd agree, then, that when a human copies from a PDF manually there's a substantial chance of them introducing errors?
Are you and I not equally vulnerable to making such mistakes? Frankly I find it absurdly wasteful that the industry has transistors in the same package but with different pinouts and the 'solution' to keeping this stuff in order is... senior engineers checking junior engineers' work against PDFs manually.
I dunno. I've used others, and KiCad was no harder to start with than the others (Horizon, LibrePCB, Lepton/gEDA, some others I forgot).
I asked for recommendations a week ago on HN for EDA products, and tried them all.
You know which one I eventually settled on? The one with the most components (symbols + footprints).
Turns out, features are nice (rules checker, etc) but not having to f*&^ing create my own symbols for a mass-produced part, then design the footprint for the same part is a huge timesaver.[1]
For many of us non-professionals designing a board, the UI just isn't as big of an issue as having to create our own components.
[1] At any reasonable hourly rate, having to create a library of just 1 component costs more than whatever you think you'll save with a slicker UI.
In terms of decoupling designs etc., the reason nobody has come up with a better solution is firstly that it doesn't actually take up enough time in the scheme of things to bother, and secondly that you often have to deviate. For variable regulators for example, the output capacitor (and inductor if it's not included in the device) are chosen based on output voltage, the switching frequency you choose, and sometimes other variables. You often want to deviate from the recommended circuit in the application notes for various reasons.
I'd think of a circuit board production as more like putting together a magazine than working on a software codebase, where you'd have a bunch of people working on overlapping parts of the code.
I mean even for a lot of boards we do (even quite complex ones) we'll just have one design engineer and one layout engineer, but for things where multiple people work on the schematic we just have people work on their own sheets and then somebody brings them together into the final design - kind of like where you might have an overall designer/editor that pulls a magazine together but individual people having put together individual articles. But it's pretty common that it would still be mostly laid out by a single engineer unless you're doing something extremely complex...
However I do want to mention that I think it might be necessary to be able to "cross-compile" to visual schematic format, and back. Or perhaps there is an open schematic tool that can be extended?
The issue is that I think electrical schematics are significantly more familiar to EE types, contain more legible information. Instead of reinventing the wheel there, it'd be nice to see a system that can switch back and forth between text and visual schematic.
How are schematics described as files currently? Is there an open standard? Can it be converted to atopile format, and back?
edit: just wanted to double down on this being very cool though. i dont mean to deflate this project and I'm about to design a pcb for a personal project - I might give this a go for fun. the promise is there and asthe project and feature set grows i can see it being the way forward.
What we discovered is that:
- making a visual viewer is a non trivial endeavor. It takes a lot of time but the value add is marginal for an average viewer. - people tend to spend a lot of time making the viewer look good instead of improving the circuit
We think that in the long run, a viewer could be awesome to inspect what is going on or get a general understanding of the circuit. But it’ll be difficult to justify the time spent on it early on in the project.
We also think that there might be better and more interesting ways to view your data, for example maybe you want to just see all the power paths through your circuit, or investigate how a signal travels from your input to your adc through filters, protection etc. Often on big designs these things might be strewn across multiple sheets and a bit hard to follow.
But take the example from [0] of a voltage divider. I agree that that is a textual description of a voltage divider that can be compiled to a netlist, a BOM, etc. But what is the actual division properties? What's the combined tolerance stackup? What I /want/ to be able to do is define a module generator function that takes a ratio, a desired output tolerance, and a maximum output current and generates the divider module with resistors chosen (both resistance and tolerance) that will meet those properties. And while I'm wishing, given that (for low output currents) this is an underdefined problem, I'd also like a way to lean towards components already in the BOM, either by just manually using preferred values (yuck), or by outputting multiple possibilities and having a selector downstream that does BOM line count optimization.
Besides taking much, much more of the drudge work out of this, it also makes these circuit-as-code text files reviewable, in much the same way code is. Consider an input pin for an ADC on a microcontroller. On the signal path, I might have at a minimum a voltage divider to get things in range, a low pass filter to get rid of aliasing, and a buffer to satisfy the input pin impedance requirements. If this is three different modules, each with two or five components... reviewing this is equivalent to designing it, I need to check each bit. If, instead, this is generate_divider(1/3, 0.1%); generate_lowpass(200 Hz); module my_standard_opamp_bufer -- then I only need to review those implementations once, and can trust the use of them (for, potentially, dozens of ADC pins).
We are working to add an equations solver to our compiler over the next few weeks, which will allow you to do things like set the ratio of a divider and total resistance, then have the solver pick optimal values based on availability, cost etc.
I think that gets really exciting when you start to be able to link these together, its trivial from there to directly set the output voltage of a power supply in volts, which will internally configure the feedback resistor divider.
Also verified designs will be super important. Its a little crazy that the status quo is you will almost inevitably make a silly mistake on your first spin. I am imagining designers will go off, make a new circuit, build and test it then make a PR to merge it into main.
atopile (1) — convert ASCII to pile of electronic components
I understand that auto-routing is not a solved problem by any means, but there should be more efficient tools to make it easier. I shudder to imagine laying out some big LED matrix without more advanced tooling.
The only issues I've had is how it outputs circular things for cutting - it does a series of polygons (configurable number), rather than an arc/circular - places like send-cut-send won't accept it, claiming it causes issues with their machines.
In that vein, I'd imagine it would make lot of sense to build a lisp on top of that, macros and sexpr manipulation are very much the strong points of lisps.
I wish you the best. Among other things, you are reinventing Verilog and other attempts. Yet, of course, evolution does not happen without people who are willing to devote their valuable time and effort to consider new ideas.
My personal perspective, after having designed hundreds of PCB's, is that there's a reason for which symbol-based data entry has survived decades of computer-based circuit design evolution.
I have also written more software than I can remember in more languages than I am able to list. I have less than zero interest in using a software process to describe circuits of any kind. What makes sense for hardware design inside an FPGA somehow does not translate well outside the chip.
Software and hardware engineering are very different things. It is probably correct to bring-up the fact that many have tried to turn software engineering into precisely the opposite; dragging symbols around and connecting them in schematic form. That approach has failed but for the most trivial educational tools.
> Could you imagine the pain of building an entire software product using only assembly code? That’s about how we felt designing hardware.
Having done this dozens of times, I don't think it is painful and don't see a parallel between assembly coding and designing electronics. In fact, assembly coding is easy for the professional experienced software engineer. Of course, it is probably close to a nightmare for someone who's never done it or never even studied machine level coding. Ballroom dancing is impossible for me. I am not a dancer. And it should be in a range between difficult and impossible for anyone without the requisite training and practice. So, that's not the right metric.
Drawing schematics is easy. Schematics convey lots of information quickly. Function, structure, constraints, implementation notes, support/service notes, fabrication guidelines, etc. Also, they are trivially and instantly easy to understand, gather around and discuss. They present a mental image and state that would require fairly deep concentration to develop if reading a schematic as code (except for trivial circuits, which don't really matter). Schematics, as I said earlier, have survived the test of time for a reason: They work.
That's not to say a different approach isn't possible. All I am saying is that I would think hard before attempting something that very clearly few engineers want and care about.
For reference, I started life drawing all of my schematics and PCB layouts by hand. I then transitioned to using AutoCAD v1.0 and writing tons of LISP code to make that easier. From there I migrated and used a bunch of tools most experienced EE's have touched: OrCAD, Protel, Mentor, Cadence, Altium, KiCad, Eagle and likely others I can't remember.
Oh, yes, I also completed a few layouts back in the day using X-acto knives and stick-on traces and doughnuts on vellum. That was fun.
This page shows a number of approaches. I all of these back in the early 80's.
https://www.pcbwizards.com/handtape.htm
Yes, that's a roll of black tape she is using:
https://i.imgur.com/yUgZ5zz.png
Schematics are not the problem.
This isn't intended to discourage you at all. All I am suggesting is that you might want to interview 100 EE's and see if this matches the idea of "build something people want". Don't interview software guys who tinker with electronics as a hobby (unless that's your audience). Interview real, working, EE's with 10+ years of experience using EDA tools from different vendors and generations. My prediction is that you will quickly discover nearly nobody cares about moving away from schematics. You will definitely find other pain pain points, just not schematics.
This product would not work at all for any analog or power designs--EEs like to visualize current flow and a schematic is the best way to do that. Maybe if it could interoperate with small blocks of schematics, treating them as modules, it could be useful. If there was a way to parameterize part values, like those used to build analog filters, that could also be useful, but not in the current text-only form.
The one thing it could be useful for is creating net connectivity for large numbers of pin to pin connections, like DDR memory or PCIe buses. Schematics for these end up looking like large data tables anyway, and can be tedious to create and prone to errors.
I see so many EDA startups using their product for simple Arduino boards and other low to medium complexity designs. It's far more effective to start with the most complex board design. Take a server board from the OpenCompute project with a few thousands parts and a few tens of thousands of nets. What would that look like in this language? Would it have too much boilerplate code? What would the experience of creating it be like? How do you handle back annotation? How do you handle pin swaps, or part section swaps? How about BOM variants?
I think OpenSCAD neatly demonstrates the issue with 3D modeling: when you come from a tool like Blender it might look amazing that you can now trivially change dimensions mid-design, but what you're really looking for is the parametric modeling you get from something like Solidworks.
Schematics-as-code doesn't solve a problem I am having. What I want, is for an easy way to import "snippets" in KiCad: I want a library where I can select an MCU, and it'll automatically add all its auxiliary parts too and let me choose from a few pre-made standard routing options. Maybe even make it parametric so it becomes a nice little wizard where if I'm adding an LDO I can enter a voltage and it'll calculate the adjustment resistors for me.
Counterintuitively, I do agree with your points. We didn't end up designing the ato language because we actively wanted to end up there but rather because we tried everything else before and none of the solutions we tried worked out.
The problem we wanted to solve was: "how does git look like in hardware?". Another way to phrase it is: "How can groups of people coordinate and share their work in hardware?".
The first solution was simply to put KiCAD on GitLab. That solves the version control part of the problem but doesn't solve consistency of design outputs, coordination and reuse problems. The we tried to add automation on top (namely with KiBOT) to generate manufacturing outputs automatically. That was pretty cool for consistency of manufacturing outputs but it didn't solve the coordination and sharing aspect of the problem. And so at that point we kind of had ran out of ideas of things to try. And that's when we started developing the ato language.
Schematics are definitely a great medium to share a design with your peers. But we've found that for those other aspects I mentioned, code is more suited.
Take that away and I'm switching to point-to-point wiring. :)
What stops electronics from becoming like programming is the routing. It's NP hard and even the big car companies haven't solved it yet, let alone any tool accessible to hobbyists and startups.
So you spend an hour designing the schematics, a few minutes placing the components, and then hours doing the routing by hand. If your product only replaces the first step, that'll save me at most 10% of the work.
If you want to make a crater in this industry, add an autorouter to KiCad and make it sophisticated enough to handle an ESP32 2-layer board without manual assistance. Altium is like $15k per year and cannot do it yet.
The physical positioning of big components or IO is usually an important requirement that needs to be frozen early on, so that mechanical design on casework can proceed in parallel.
it's non-trivial, you need to fiddle with parameters to encourage the autoroute towards certain behaviors. there are also some schematic patterns that lend towards better netlists and in turn better routing
I then built a little CLI tool which used bitmap images and ConvNets to do just that one fan-out, but then I lost interest in it as soon as the PCB was finished.
module blinky
(
input v3v3,
input gnd
);
wire led;
wire led_r;
rp2040 u1
(
.vcc (v3v3),
.gnd (gnd),
.gpioa15 (led)
);
resistor #(.VALUE("220"), .TOLERANCE("5%"), .PART("ERJH2CF1R10X"), .SIZE("1206")) r1
(
.a (led),
.b (led_r)
);
led #(.PART("WP7113SURDK14V")) d1
(
.anode (v3v3),
.cathode (led_r)
);
endmodule
Use Verilog parameters for all of the part information you might want, like links to digikey part number.. or bury them into modules with different names.FWIW: Cadance "conceptHDL" is a schematic entry program which generates a Verilog netlist like this as its output (usually for board level simulation including ASICs and FPGAs). But if you're careful, Verilog could used directly as the input- the board-level schematic is pretty simple compared with the chip source code.
I'm sure there is a tool somewhere to convert this into an EDIF netlist for Kicad or whatever. [Icarus can do it: https://steveicarus.github.io/iverilog/targets/tgt-fpga.html ]
Also: this is not limited to digital: there is a variant of Verilog called Verilog-AMS specifically designed for analog simulation.
https://en.wikipedia.org/wiki/Verilog-AMS
In Verilog-AMS, you can define a simulation models of your components:
module resistor
(
inout electrical a,
inout electrical b
);
parameter real R = 1.0;
analog
V(a,b) <+ R * I(a,b);
endmodule
module capacitor
(
inout electrical p,
inout electrical n
);
parameter real c = 0;
analog
I(p,n) <+ c*ddt(V(p, n));
endmodule
So not only do you get a component, but you also can simulate the whole thing before fabrication to catch mistakes.There's a few parts we think that are behind that, but one is similar to python's/Guido's "code is read more than it's written", so we're attempting to address that!
Units and tolerances are core to our language, the physical world is 'fuzzy' and having a good way to deal with those we think is pretty important.
We are also trying to make it as readable and friendly as possible, our expectation is our users will likely have some experience with python and perhaps a little C back in school, so making it clear and approachable is front of mind.
Very open to critiques on our choices! We still very much in development.
Have you got any plans for defined interfaces/modularity so devices using SPI, I²C, etc. can be chained together without manually defining pin connections? Also, will there be support for importing schematics from other formats?
Interfaces are just a collection of signals eg
interface I2C:
signal sda
signal scl
signal gnd
you can connect two together like so:
micro.i2c ~ sensor.i2cImporting schematics would be possible, but IMO not super valuable as all we could import would be the raw connectivity, a big benefit of our language is being able to add a layer of abstraction on that.
Python's performance problems are unfixable without wholesale redesign of the language and standard library. Its package management is a bad joke. The developers give no indication that they have any intention to fix those problems, rather than keep stuffing more unnecessary and badly thought-out features into it.
Obsolescence should be gauged by how modern the design of a language is, rather than its popularity. By that measure, Python is manifestly obsolete, and has been even when it debuted.
When I was thinking about it, a couple of further directions I had in mind were 1) ecosystem/library/sharing of modules, so something like the voltage divider example is not something you'd need to do (even once) for every project; if it really took off the pipedream would be that application notes examples were just provided as modules, so you could take whatever IC wnd just import the module if you were using it in a standard way; 2) if you did a similar thing for layout constraints, you could then have that as part of the same module, and when you compile the whole thing (in hand-wavey generalised theory if sufficiently constrained) you could generate the overall layout for a project with say a SMPS and also sensitive analogue circuitry in a way that makes sense without either of those modules having to know that the other is in use, just because they have rules like distance from transistor, bypass cap to IC could be fully constrained, so you always get exactly the same sensible-looking layout, etc.
Anyway, looks great, I look forward to trying it properly some time!
100% agreed about the ecosystem too. We've already created a perhaps-too-scrappy package manager, but it works! https://packages.atopile.io/ We're pretty convinced that the awesomeness of the software ecosystem is a function of its openness and open-source and atopile largely came from working out how we could seed a similar shift in the hardware world. I can't wait for the day I can `ato install` SMPS, filters, radios and servo-drives with the confidence they'll just work!
It's quite difficult as a beginner to know that a design is "correct", or perhaps "correct enough", with respect to component placement and EMI.
It seems like even top EE who specialize in board design utilize rules of thumb rather than rely on simulation.
I was also blown away that the state of the art autorouter for traces seems to be from the early 2000's -- no recent AI magic going on here.
Where is my "autoplacer"? It seems like an AI trained on millions of schematic/pcb combos, even just gerber files via image ingestion, ought to be able to generate a pretty decent layout + routing given constraints.
Or perhaps I'm spoiled coming from software and web because it's so much further removed from physics. But it's still the case that there are a ton of modular components with "API's" that should have a templating language, so very much bravo to this project.
Declarative: the code describes the desired result.
Imperative: the code describes the operations to take.
Most programming languages are Imperative, but some are Declarative, and some allow a mix of the two. More here: https://www.educative.io/blog/declarative-vs-imperative-prog...
People have tried many times to build a universal router with physics awareness for decades. The issue is in the real world there are countless edge cases where the EE must make a decision on the layout.
For low speed digital design... routers have partially worked since the 90's, but for most other things the edge cases make it counter-productive to automate.
EEs are good people to have around, and some know how to build things reliably.
Have a wonderful day, and I really hope the project does well. =)
Our goal generally is to automate tasks that are boring/repetitive like multi-day reviews of big schematics to see if anything accidentally changed. Definitely building a lever for EEs, not a replacement.
Thanks!
I set up a CI pipeline for the hardware company I worked for. It automatically generated things like gerbers and board renders for each commit, and made them available as PNGs. I added a little tool which made it really easy to view the results side-by-side, and see both the front and the back. It definitely saved us from some really expensive mistakes a few times!
Because hardware tends to be informed by messy physical factors which are hard to represent programmatically.
Think along the lines of "the cables are coming from this side of the board", or "buttons need to be reachable by fingers", or "if you're building a weather station, the temperature sensor should be far away from components that generate heat".
I think KiCAD gets a lot of things right. Some of the broken things:
parts management (There is no central repo, a la LVFS, where I can get a part/pinout/3d model to easily import)
export process (feels kludgey, although some manufactures take the native KiCAD files)
multiple users, same project -- it's hard to put artifacts into git and merge changes.
I see this solving the last issue, perhaps the second as well. Commercially, I think it is worth pursing the first.
Other thoughts:
When I spec parts for certain types of designs, I need a whole lot more than just tolerance. e.g, for a mlcc capacitor, I need to spec dielectric, voltage, tolerance, ESR, sometimes leakage. For resistors, inductors, and other jellybean parts, similar metrics apply. Specing active "common" parts (like bjt/fet, diodes, etc) has even more parameters to consider.
I would also love the ability to take a design and drop it into SPICE for simulation.
Being able to use git was our fundamental motivator, we all previously worked a big companies and found it maddening that we couldnt work in parallel on projects without breaking everything.
On parts specs, for sure, we currently capture all the data you would see on JLCs website. We do have dielectric and voltage ratings for caps. Eventually we plan to scrape a bunch of datasheets to build out a high quality dataset, I am very excited about this!
One lesson of this thread could be: There is enough interest in text-based "schematics" -- aka netlist import -- for Kicad layout to add support for the approach, if it does not currently exist.
I fear a lot of this is due to manufacturers. There are quite a few variables in the file definition, and every manufacturer requires them to be set slightly different.
Having pre-baked per-manufacturer templates in a dropdown box would already be quite the improvement, though.
[1] https://doc.akka.io/docs/akka/current/stream/stream-graphs.h...
I wonder if with directional arrows, instead of writing "out ~ switch.in; switch.out ~ power.gnd", we could write "out ~> switch ~> power.gnd" instead?
But without distinction between in and out ports it may not be possible to check if connections are valid ones.
Anyway, this project really makes me want to learn electronics! Congrats!
The equivalent of atopile signal would be port with Akka I think. A combination of ports gives us a shape. A source shape is just one OUT port. A flow shape is one IN and one OUT port, etc.
I'm very new to electronics so I don't know if it makes sense, but connecting all these ports with directional arrows was really helpful to understand the data flow.
I'm doing a lot of home automation work, and I absolutely hate that I need to use breadboards, hunt for pre-assembled components, or to spend days designing a PCB for simple things like relay modules with customized IO.
E.g. I have ratgdo for my garage door opener, but its power supply is an ugly buck convertor taped to the box. I'd love to just re-make the ratgdo board, but with a built-in 12V-to-3V buck convertor.
I tried that, but PCB manufacturing with custom component placing requires just too much work.
Is there a way to donate to the project? I'd love to support it.
Have a look at packages.atopile.io. We have a package with power supplies that you can just add to your board with
ato install regulators
https://gitlab.atopile.io/packages/regulatorsBest way to support us right now is to try the project and give feedback on where you'd like to see this going. The project is open source so feel free to raise issues or contribute as well :)
This would make it easy to implement a fancy optimizer. Each component tends to have certain acceptable thresholds for their dependencies like input voltages, current limits, external resistor/capacitor/inductor values/ratings, etc.
Then, each component could have different implementations. You can have different manufacturers produce the exact same inductor/capacitor/resistor in different packages. You can link it up to your existing BOM or hook into vendor APIs to get pricing.
Imagine optimizing for cost, removing redundancy, simplifying footprints, and prioritizing in-stock inventory over new order components.
This could be a huge deal, looking forward to its progress
Here's some of the basics Tim was playing with earlier: https://github.com/atopile/atopile/blob/d25686952534e0f96582...
Are you fully open source today? How has the community aspect been going?
I tooled around with a similar idea sometime back. There are clear advantages of code over graphical-schematics when it comes to automatic generation of component values / re-use of elements / speed of development / automatic SPICE testing / etc.
The primary issue I ran into was that: electronic circuits are inherently graph-structured and the traditional circuit schematic is well suited, optimal even, for displaying this kind of information. Trying to understand an analog circuit that is described as code seems awkward.
I think a viewer would be nice ultimately. But we haven't exactly figured out how the solution might look like. ideally something that allows you to create datasheet-like snapshots of part of your design?
Side-by-side schematic symbol view / code view that are actively synced to one-another in real-time. Schematic view allows basic arranging of parts, editing interconnects, triggering jump-to-reference within the code view, adding probe points for SPICE, displaying SPICE output graphs. Code side does all the heavy lifting like creating new parts, scripted behaviors, editing component values, all the cool shit that would be a nightmare to sort into a GUI.
Much easier said than done, of course.
You still need heavy EE understanding to know how to develop PCBs, so it’s not going to turn every software engineer into a PCB pro, but it could totally change the game for EEs that can learn to code.
This is definitely a step in the right direction though and I’m wondering how much of a PCB can be represented in an abstract syntax tree or something similar. Are there edge cases, or could you completely describe a PCB layout using code?
We're honestly not sure how explicitly we want to describe a layout in code, or if it's a more declarative thing. Currently we're leaning more towards the declarative approach (eg. this trace carries 100mA of current) rather than the imperative (this trace is 0.150mm wide) since it should scale more intuitively with equations and layer better with DFM specs etc...
Have you got some ideas?
Idk maybe this can be solved, but seems problematic to describe layouts like SQL then rely on query planners to deliver the perfect execution.
- First, requirements. In ato, you define how your circuit is connected and the requirements for the components that sit within it. From there, we generate a netlist and a BOM.
- Second, the netlist is turned into an actual object during the layout operation. We use KiCAD's layout tool in our case. There are infinitely more dimensions in the real world than there are instructions in a computer. So we do need that second step to point the requirement to one implementation in the real world. But technically there could be a quasi infinite implementations that fit the requirements written in ato.
The manufacturing files are a combination of the ato output files, like the BOM and the KiCAD output files, like the gerbers.
This iteration of the project actually came after first working with and then modifying another awesome project called SKiDL (https://github.com/devbisme/skidl).
It's based on Python - but we found that since it's procedural, turing complete and has a rich eco-system - people use to that and there aren't standard composable ways of designing things. Instead of describing your board, you (practically) write a script that generates your board. It entangles your targets with your source-code and can make it difficult to understand the ultimate outcome of what you've written.
Additionally, since it's a potentially very long program, it was hard to write good language support around (a language server for VSCode, a schematic visualiser etc...) that were snappy, responsive and lent to examining modules as well as the whole program.
There's a few operators and first-class language features we wanted as well, like units and tolerances (3.3V +/- 100mV) that just aren't the same when embedded in a string, or class init method.
Is this meant sarcastically?
I love the graphical nature of Schematic design. It helps me visualise problems that my colleagues would admittedly rather code. I take a lot of care in my schematic layout, and it can help me make a good guess as to wether my circuit is planar or not. - usefull when you dont want to incurr the parasitics on a via somewhere.
I would also remark that there is no reason why design reuse would necessitate a text based caprure. We already have reuse though subsheet heirachy, ctrl c/ctrl c and to some degree reference designs.
The only other thing I would add is that a lot of people come from a hobbyist background, which means small volumes. For commercial contract manufacturing, drawing out the same old schematic features for voltage regulators doesnt add up to much NRE as a fraction of the project cost.
The point we would like to move towards is one where atopile enables you to generate high quality documentation about your design in a similar fashion to a datasheet but not entangling the documentation with the source design, which is what a schematic forces you to do. There are some features we'd want to build that could enable that like a visualizer for important parts of a schematic, a fan out view of the consumed interfaces around a chip, the results of a spice simulation...
The open source aspect was really important to us. We are hoping that ato modules can become a convenient language for the community to share modules with each other, in a similar fashion to python and pypi.
Having an open code base also makes it more convenient for our users to chain tools together. This is currently hard to achieve with the existing close source standards we are dealing with in hardware.
ato is also a markup language (like markdown or latex) more than an actual programming language. We think this makes it more readable and helps guide the user writing code that compiles.
One small thing regarding the imports: If you plan to have some rich autocomplete functionality (which helps dicoverability of packages) it is better to have the source of something first and the imported stuff afterwards. Python - which you seem to draw inspiration from - does this as well:
from xy import z
The editor can offer auto completions when the cursor is after "import ", which is not possible if it's the other way round: `import z from xy` (like it is in JS).I'll try this out, it looks very promising!
Did you see the ESP32 in the package registry? https://packages.atopile.io
I've done both. What you called "pain" I called "fun". I started life as an electronic engineer but am now a software engineer and was very comfortable in both areas--including building from the TTL level. So I'm automatically suspicious of anything that calls such things painful.
My kneejerk reaction is "you've never done this professionally" but it's 3am where I'm at and can't watch the video right now.
Ultimately we do love electronics. This is one of our attempts to contribute back to the field.
Import from public GitHub libraries could be fun.
Differential pairs.
Impedance controlled traces.
Going further, if I have one supplier's stack up with controlled impedance lines, and I need to switch to a different supplier's stack up, what netclasses would change?
On the language side there are additional features we would like to work on like traits and types (types would include diff pairs and impedance).
If I may add my two cents, I think you should concentrate on making it possible to go beyond lumped element models (which can already be simulated using SPICE, etc) and simple abstraction (solved by VHDL & co) and focus on being able to offer advanced subsystems to less experienced PCB EDA users. Basically, to go for the Altium path, but without Altium. For example, it would be a killer feature if it were possible to import an FTDI USB chip module and a switching power supply module, and obtain a PCB that has a guarantees (up to a degree) that the two will not interfere with each other. Or say, have it automatically optimize a design to guarantee a certain SWR [3].
[1]: https://www.analog.com/media/en/training-seminars/tutorials/...
[2]: https://f4pga.org/
BOM generation and abstraction have definitely not made it to PCBA design yet, so that is where we are starting.
Stoked to get to the hard stuff.
I'm just starting with electronics, following the Make Electronics book with my kid. And this seems super useful to understand circuits better (at least for people who code), do you have the plan to make a series of lessons for beginners with the app? Like going from the simple battery-led to complex things? Feel free to email.
Really love that. My dad gave me a piece of wood with some basic components like LEDs, motors, resistors and light bulbs and a battery that I could connect those to and understand how they worked. Glad to see you are doing something similar :)
We do have a couple videos and certainly plan to make more: - Get started guide: https://youtu.be/7aeZLlA_VYA - ESP32 module: https://youtu.be/eMWRwZOajdQ - Logic gates kit: https://www.youtube.com/watch?v=hSeDv3QqRc0
We are also hoping for the package registry to become a place where you can get access to pre-designed modules to put together into a circuit: https://packages.atopile.io
Feel free to reach out per email or discord if you need help setting things up!
We did use skidl for a little while as we were figuring things out (see a project here: https://gitlab.atopile.io/pew-pew-and-friends/sizzle-sack). But we later ended up moving away from it towards ato for mainly two reasons:
- Baking a description of a circuit into python describes how to obtain the circuit, but doesn't really describe what the circuit is. Skidl projects quickly become hard to read. The user is also not guided towards writing code that compiles since you need to deal with all the complexity of Python as well as the circuit itself. - Contributing to the project and adding features was non trivial
Chip fan out modules. A repo of all popular chips with traces to pins fanned out and variations (Chip XXXX, Fanout A, Fanout B, Fanout C, Compact Fanout D etc) Ideally the fanout modules should have required decoupling caps etc placed compactly).
Accommodate provision for chips such as i.MX 6ULL, the have so many pins that writing connection code would be daunting, maybe have pin groups and groups wired to groups syntax.
Provisions for chips where pins can be configured.
A repo of supporting circuits/modules like clock, clock distribution, PMIC / Power modules etc.
A CPU for example module should come with a list of compatible auxiliary modules such as a suitable PMIC/Power module.
The user will have to wire the relevant pin groups from module to module.
I'm also curious if you're able to use an autorouter to minimize board layers. Seems like it should be pretty straightforward to apply some graph theory to this and state the minimal number of layers for a given board, but this also might be NP-hard? I haven't kept up with the theory here.
I think I see the entry point for auto routing to be taking advantage of the fact that layers have become pretty cheap (atleast for prototyping) and engineering time is the expensive bit. If the tool can help me layout a board in half the time, particularly for test hardware or the likes, that would be huge. Eventually I think we will get to a place where computers will do a better job of layout than most people, but thats a ways off.
I am very excited to use this!
My optimal workflow would be, to use code for describing the netlist using components, then use a combination of graphical and code editor to layout the PCB, like how the UI editor in Android studio used to work. (I don't know if it still works this way) I'd love to layout my components using UI like in the CAD program "Onshape", which let's you set your constraints visually and the program visualizes conflicting constraints.
I would love to start working on a project in code and then make an export into KiCAD to make final changes and send it off. Then, as the project gets further along, the point where I would switch to KiCAD would gradually shift further and further towards production. If I see this correctly, you are already aiming for that and I commend you for that approach :)
I haven't actually used Onshape, so I'm not intimately familiar with their constraints system. Thank you for the recommendation, I'll have to check it out for some hints.
Eventually it would be amazing to import (for example) a buck converter circuit with a wide voltage input, fixed output suitable for RF, and have it automatically check available components at JLCPCB and then lay it all out with, adhering to best practices (ground planes & capacitors right next to pins etc.) If the available components change, it can tweak the footprints and layout without having to start from scratch.
Good luck, I’ll be following closely!
Looking at your demo video, it seems that atopile is less a "tool to build electronic circuit boards with code" and more a tool to perform schematic capture in code. Do you agree with that characterization?
I ask that question because you're clearly relying on the KiCad toolchain for PCB layout, which is a crucial part of the overall PCB design process but is not "PCB design" itself. Right now, KiCad is a tool for PCB design, and you are providing an alternative method of schematic capture. I think you should make sure that the description of your creation accurately reflects its capabilities.
Is anything preventing you from taking output from the existing KiCad schematic representation system and transpiling it into ato? What about transpiling from ato into the KiCad schematic representation system?
Does ato provide any focus on routing? It could be nice to state in software that I want a component or trace constrained to a specific layer on the PCB (or in the PCB, if there's internal layers). I'm assuming no, since ato appears to be purely focused on schematic capture, but I'm curious of your thoughts on this.
It could also be nice to include placement constraints in software. For example, say I have a handful of resistors which I want placed in the same relative area of a board and in an orderly row. Do you provide functionality to allow this? The general aesthetics of PCB layout might be programmatically defined with ato.
Just like Arduino took the nitty-gritty away from microcontroller programming, think about how you can take the nitty-gritty away from schematic capture. One way this could work is with a hierarchical schematic templating system. You'd need to build significant documentation to teach people how to use it, but it could vastly simplify the schematic capture process to a few lines of code by importing a template schematic class and instantiating multiple schematic objects into a project and wiring them together.
It makes sense to me that an "interface" as you define it can be imported for a given project. For example, "Bob's Interface" is the set of a +12V barrel-type power input, a USB-A port, a 3.5mm headphone jack, and a 10-pin GPIO header. Any project using "Bob's Interface" has a known set of input and output capabilities. The term "input/output complex" also gets at this idea. Is that how you think of an interface?
That's all for now. :)
That said, we are absolutely looking to take on the layout section in the near future. We are starting with some augmentations of kicad, for example we just released a layout reuse feature, where component layouts can be captured and shared along with the ato code.
I think with few exceptions defining explicit layout choices in our language will be painful and not the right path (perhaps connector positions would be an exception). We have not put a huge amount of energy into this yet, but from some initial playing around, we believe capturing all the information that a person would use to judge a quality layout will be crucial. For example, current tools do not have concepts of current/voltage and definitely not transient behavior.
To get to actually good auto-layout that doesnt suck is going to be a slog for sure.
Thanks!
Maybe I've been writing too much React and Android Compose UI lately, but instead of a declarative structure, have you considered a functional structure? That seems to be a create way to build composable components and add enough programmability (e.g. loops, conditionals) and keep a nice one-way flow down the line.
Something like
``` import {Resistor, Signal, Ohms, Float} ...
def VoltageDivider(totalR: Ohms, ratio: Float, signal1: Signal, signal2: Signal, signalOut: Signal) { r1 = Resistor(totalR/ratio, signal1, signalOut) r2 = Resistor(totalR(1-ratio),signal2,signalOut) }
def MyBoard() { s1 = Signal() s2 = Signal() s3 = Signal() div1 = VoltageDivider(totalR: 100_000, ratio:.33, signal1: s1, signal2: s2, signalOut: s3)
}
It's similar to what you have but maybe a bit more of a programming language than a declarative format. The trade-off is that tooling support gets harder as you add some basic language features, but the upside is a more powerful language.
0. computer science
1. arduino programming + very basic circuits
2. adding a few chips and talking to them through I2C/SPI: still in digital circuits territory, sending 1s and 0s
3. designing my frist PCBs with kiCAD: a huge learning step, and things start to get a bit messy (component tolerance, transmission delays ...)
4. looking at analog circuitry / alternative current / signal processing : a HUGE uncharted territory, full of promises and headaches.
This trajectory is probably quite common, and I'm sure atopile has a role to play there, when you start growing out of arduino. Making things a bit smoother, searchable, reusable, being able to learn from other people's design - what a wonderful tool it could be!
Yes, we hope for the packages.atopile.io to become a place where you can share your designs and explore what other people have built.
https://observablehq.com/@nturley/netlistsvg-how-to-draw-a-b...
HDL tools all do this.
I'm sure we will have some flavor of a visualizer in the compiler one day. But outputting a "normal" schematic doesn't seem like it's the right approach. We might actually end up with a bunch of different ways to "visualize" your circuit, each one optimized for a specific thing you are trying to achieve.
We also noticed that most EEs we've worked with were a bit put off by the syntax and preferred something a bit more terse, but more intuitive and easier to read.
There perhaps an analog here in software - where we started with assembly (~ SPICE), moved up through things like C and now languages like Python and JavaScript are prolific and accessible.
But to add to the wishlist of innovations in PCB layout; someone please give us better gerber editing/conversion tools. Geber strikes me as being very like pdf -- absolutely standard, well reproducible, but awful to edit in any way other than 'intended'.
https://github.com/Timot05/logic-card/blob/a63581636233dd1f9...
This is a hole we're planning to fill between linters and a language server. Picture a red-underline under an instance which is insufficiently configured, for example
This has a VS Code extension, but I don't use VS Code, I like to use other editors like Kate.
Having a LSP Server and xml for syntax would be a great feature.
I think an LSP server is what we're really excited about, since it also means we can provide far richer autocomplete and inline docs as we go too.
Most PCB tools have the user create the schematics graphically, but the actual 'design' is usually a text netlist already or the tools let you export the netlist to an industry format such as EDIF.
SPICE netlists (for example) are also purely text-based, and while many of my EE professors could actually "think in SPICE" (i.e. go from a schematic of a circuit to directly writing in SPICE) for me and pretty much everyone else it was unbelivably painful to modify a SPICE netlist as you went from a simple inverter to something even "basic" as a two-transistor BJT current-mirror. You want to now copy+paste the design six times? Now you have 6x netlist re-naming fun.
One of the reasons why non-trivial schematics are done graphically is you can more easily grasp the intent of the design and make "complex" designs very clear. In my opinion, it's a reason why a well designed block diagram is worth 10x access to the "design" whether it's RTL or C -- you get an understanding WHY someone did something not just the what.
Example, you might put resistors in-series on a bus to provide termination (best done at the source/driver) ; what would that look like in this new text-based schematic language? What if I have series termination resistors on the bus, thevenin termination on the far-end and then a pull-down strapping resistor as well? The block of text will grow quickly without much clarity. I don't doubt it will be functional, but there will be no mental model of what this is supposed to look like, and further why all of these components are there. A well drawn schematic* will make this overt.
Another simple example might be a single-supply op-amp which usually has a few resistors to bias the signal correctly. It will easily end up being MANY lines of text and it won't all together be clear which lines of text associated with the op-amp correspond to an intent.
I have about 20-years of doings electronics, FPGAs, boards, C/C++, SoC architecture and DevOps with a formal education in both HW+SW. I could be an example of "the old guard" but in my career I've usually been the one to champion newer/smarter better tools and applicable domain-specific-languages so much so I pivoted my career in this very area for a number of years.
*Most schematics, and reference designs are a jumbled mess of wires and symbols. While highly subjective, a good schematic breaks logical function into symbols by function, groups related components intelligently and employs a good number of notes on the schematic.
Currently when you discuss configuring a regulator, it's beholden upon the designer to understand enough of the internals to configure it because, in our opinion, schematics aren't well suited to designing things that are configurable and plastic - either in topological terms, or in their parameters. Our hope isn't to abstract this complexity directly by using code, but rather because code allows the workflow itself to change, for a well tested and trusted configurable block to completely abstract the internals such that a designer can forget about it (like a tested piece of code). We want to bring configurability on this "trusted" scale in from the physical world of modules to the world of highly descriptive code. It's a tall order, I'll indeed admit!
It's also well worth nothing that while at the moment we're running lean on the visualisations, we do agree they're an extremely potent tool to convey the topology of a design at a glance. We expect we'll be adding a visualiser which should be used to gain familiarity with a circuit, diff it for review and understand it from a system level (by viewing topology by interface type etc...) - unlike current schematics that implicitly hold so much content via the positioning of components.
Thanks for the detailed comment!
[1]: https://nfb.org/sites/default/files/images/nfb/publications/...
For circuit board design we are missing * PCB layer management
* copper dimensioning
* track management
* Design rules management
* many others....
At best, I would describe this tool as a vim for schematic capture in its current iteration.
One question to the founders, what are the real pain points for you that atopile are relieving?
It can be a good example of how to setup an ato project.
A simple BUY button - take away all the mess for me as "end-user" who just want a board (I don't want to spend hours of BOM files, jlpcb, soldout parts etc.) - take away the mess for the creator of building a community around a design, monetize it, etc etc.
diyBMS recently did a short video on setting up shop https://www.youtube.com/watch?v=Qkg1Fu41QHE
(also group buying would mean huge savings as pooled productions would yield big production runs.. etc.)
Speaking of it, THIS would be a killer product.
A program gets compiled down to x86/x64 assembly, and you take that LL file and generate an FPGA from it.
Of course there's a lot of limitations in regards to OS APIs, but those could be represented with an SDK (e.g. a network socket API that is compatible with linux's headers and leads to a NIC being controlled with a firmware replacement).
class Blinky
microcontroller @mc(RP2040Kit)
led-indicator @led.blue
.input(&.microcontroller.gpio13)
.gnd(&.microcontroller.power.gnd)
.resistor.value(100, 10%)
voltage-regulator @regulator(Reg3V3)
.power-out(&.microcontroller.power)
usb-c-connector @usbc
.power(&.voltage-regulator.power-in)I will try out your sw and give feedback.
An example of the produced layout would be interesting.
First thought. Where is the language definition for users?