Pangram verdict · v3.3
We believe that this text is a mix of AI and human-written content.
AI likelihood · overall
MixedArticle text · 708 words · 3 segments analyzed
In August, we published a puzzle that handed you the final GDS layout of a small chip and asked you to work out what it did. We supplied the physical layout, but not a netlist or internal signal names, and it was up to you to reverse-engineer the internals.
This post reveals what the chip does and explores the different ways you solved it, with shout-outs to some of our favorite submissions. The submissions We received about 400 submissions from more than 30 countries, the bulk from the US, India, the UK and Australia. Entrants included high school students, researchers, working engineers and retirees. Most solvers used KLayout, Yosys and Z3 alongside custom tools (many AI-written) implemented in Python, Rust, C++, OCaml, Haskell and even Odin. The solution As many of you discovered, the chip is a hardware checker for an 11x11 Star Battle puzzle, also known as “Two Not Touch”. The goal is to place exactly two stars in each row, column, and colored region. No two stars can touch, even diagonally! The chip accepts 121 cycles of inputs, with each input indicating whether to place a star in the corresponding square. It then runs several parallel checks on these inputs: A 2-bit counter for each row and every column, requiring that each has exactly 2 stars A 121-bit ROM mapping squares to regions, and a 2-bit counter for each region, requiring that each has exactly 2 stars A delay line for tracking nearby squares to ensure that two stars never touch, including diagonally. A counter for the total number of stars, used to produce certain Easter egg outputs The puzzle checks are then ANDed together to produce the success signal. The output generator stores its strings in ROM. To prevent the solution from showing up as plaintext, it is obfuscated with a small LFSR driven based off the game board (though that didn’t stop some of you from attacking the LFSR!) Once success is achieved, the output logic deobfuscates the solution string and emits it! (* TWO STARS *) Most incorrect solutions emit the string “TRY AGAIN”, but a few trigger the Easter eggs listed below. The puzzle chip was designed using the SKY130 open-source standard cell library, using the LibreLane toolchain. How you solved it Below, we walk through the steps involved in solving the puzzle, with examples from some of our favorite writeups. The first step was to extract a gate-level netlist from the GDS layout. To make it a little easier to get started, we left the cell names (such as sky130_fd_sc_hd__nand2_2) in the GDS files, allowing the use of the LVS1 passes in tools like Magic and KLayout to extract a raw gate-level netlist. Some folks, however, took on the extra challenge of writing their own netlist extraction tool. Vladislav Shapovalov’s writeup shows how he wrote his own extraction pipeline in C++ to parse the GDS, extract the shapes of each cell, and combine them with the cell names to generate a full logical netlist. He then did a process of trial-and-error with the warm-up design to debug his pipeline before using it to extract the main puzzle GDS. (Cropped from Figure 1 of Vladislav Shapovalov's writeup) Simulating the netlist Recovering the netlist gives you a circuit graph, but simulating it also requires knowing how each cell behaves. Some solvers generated Verilog and used the SKY130 cell models with an existing simulator. Others such as Stephen Ebert, built their own evaluators, computing the logic between registers and updating the registers on each clock edge.
The supplied waveform gave them an input sequence to replay and expected outputs to compare against. The same simulator could then test candidate boards and run the output generator to read the answer. But matching that waveform didn’t necessarily mean the simulator was correct. Alejandro Soto Franco describes a Python model that reproduced the supplied trace despite getting every tie-high cell wrong. These cells should supply a constant one; the model never evaluated them, leaving their outputs at zero. The mistake effectively disabled the adjacency check. A solver using that model could therefore find apparently valid boards with touching stars. Alejandro caught the problem by comparing the Python model against a separate Icarus Verilog simulation on additional inputs.