Imported from GitHub: mackenzie-norman/PCB-Climber · commit d703bf3 · license Apache-2.0
Description
This project uses a Genetic Algorithm to generate "good" pcb layouts.
README
PCB Climber
Mackenzie Norman
This started as my attempt to implement the GA described in this paper using the Rust Programming language
Note: since it is paywalled, and to make sure I knew what I was doing. I rewrote the key pieces here : GA_breakdown.pdf

This project uses a Genetic Algorithm (GA) to generate "good" pcb layouts. It can read in some .kicad_pcb files. It features a CLI using CLAP and is multithreaded using Rayon. It also uses the plotters library to make nice plots of placements.
The GA optimizes for 3 variables which are summed to calculate the fitness.
- HPWL: calculated on a per net basis. In the real world, layouts with Via anywhere don't need to worry about routing gnd so I sometimes ignore it.
- placement area: currently this is just the bounding box of all the components, ideally this should be Convex Hull or some other more accurate area calculation
- Overlap: A large penalty is added if components overlap.
Building
to build the exe simply run :
cargo build --release
the .exe will then be in
target\release\pcb-layout.exe
Usage
Now either with the path above, or just with cargo run --release -- you can run the exe and use the cli.
Usage: pcb-layout.exe [OPTIONS]
Options:
-f, --file <FILE>
Name of the .kicad_pcb file to use. Use synthetic to use the generated toy case. This probably will error on some boards. The parser was a bit of an afterthought and desperately needs more time [default: "../arduino_kicad/arduino UNO.kicad_pcb"]
-g, --generations <GENERATIONS>
Number of generations [default: 1000]
-p, --population-size <POPULATION_SIZE>
How many individuals are in our popuation [default: 100]
-t, --test
Run the testing function on our file (will override gen/pop)- right now this is the only way to see SA results too
-s, --selection
Selection Type (ev or elitist)
-a, --animate
Generate an animation
--threads <THREADS>
Number of threads (GA only), this is a bit of misnomer since its really how many groups the populations will be split into and then rayon deals with it [default: 1]
-h, --help
Print help
-V, --version
Print version
Project Structure
Main is our runner and cli, plus a helper function for generating a dummy placment if you don't have a kicad_pcb GA has our various selection operators and has the struct and impl for our individual. Kicad parse is for parsing kicad_pcb files. Its really ugly right now and kind of buggy I think. plcmnt has our struct representation of a pcb (basically, it really is just boxes and pins)
I attempted to keep an engineering notebook in little-notebook.md.
Now that I have plotting working, you can see the progress by looking at test-100x1000.png and test.md

Project Write-up
How I feel
I think this project exactly met my expectations. I still wish I could've done more.
The hard part about stuff like this is juggling between learning and results, and I think as usual I prioritized "results" over learning and kind of wish it would've been different. 10 week terms are hard. A good example is parallelism and the rand functions. I never really got any speed ups from running things in parallel either with threads or Rayon. I assume part of this is me using clone to heavily since I did not want to deal with references and part of this is my rand function. (also maybe this isnt a great parallel problem).
Wins
- Did implement all my GA functionality
- Implemented an SA too and even started on a PSA.
- Can parse a pcb (sort of)
- At least added parallel computing (using both rayon and std::threads)
Not Wins
- Ended up giving up on the discretized version of the code - I might return to this later since I still want to do it. The main reason why this was neccessary is that most pcbs don't use whole numbers and so you'd have to scale things up and round.
- As mentioned above, parallel did not result in meaningful run time improvement
- Using a lot of clones still. Not too expensive but there certainly can be some improvements.
- It seems like I broke it in one of the newer versions. It still runs but we get some overlaps which ideally would be filtered out
- Ran out of time to do any serious testing
Continuations
I do plan on keeping up with this project, if nothing else to improve my rust skills. This is what I hope to change/add (in no particular order)
- finish PSA , I really think this is the best hill climber ND approach to this problem.
- Try a more 'annealing' based approach to SA. i.e instead of using purely random movement, weighting our movement and swap ops so that when temperature decreases - odds of big movements/ swaps decrease.
- Try to get a more accurate wirelength calc - this might be something that parallel can help with.
- Maybe try a marco or some sort of expression parser for dealing with kicad files. (I really wish the kicad parse crate had worked. )
- output back to the kicad_file
PCB Sources:
https://github.com/sabogalc/KiCad-Arduino-Boards
Previous Work/Sources
- https://docs.rs/kicad_parse_gen/latest/kicad_parse_gen/layout/index.html
- https://github.com/racklet/kicad-rs/tree/main
- https://github.com/The-OpenROAD-Project/SA-PCB
- https://dspace.mit.edu/bitstream/handle/1721.1/139247/Crocker-pcrocker-meng-eecs-2021-thesis.pdf?sequence=1&isAllowed=y
- https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6269973
No comments yet. Be the first to ask about this board.