Tiny Tapeout SKY 25B Quadrature Encoder

2025-11-10

gtkwave tb.vcd tb.gtkw timing.png

hi

3D viewer

die.png 1

die half

pages 852, 877

GitHub →

https://app.tinytapeout.com/projects/3383

In November 2025 I submitted a Verilog design to Tiny Tapeout’s SKY25B shuttle. It’s a quadrature encoder interface — a x4 decoder with 15-bit up/down count and last-step direction. The chip is being manufactured on ChipFoundry’s CC2511 MPW using the sky130A PDK and is estimated to arrive around June 2026. This is the writeup of the design. I’ll follow up when the chip is in hand and tested.

What a QEI does

Rotary encoders output two square waves, A and B, 90° out of phase. The phase relationship tells you direction; counting edges tells you position. A x4 decoder counts all four edges per cycle (both rising and falling edges of both A and B), giving four times the resolution of a simple rising-edge counter. This is the standard approach for motor control and position feedback.

The usual implementation is a few lines of firmware running on a microcontroller. Putting it in silicon is overkill for most applications, but that’s the point of Tiny Tapeout — the cost to submit a small design is low enough that “because I wanted to” is a valid reason.

The Design

The module takes A and B on ui_in[0:1]. Both signals go through two-flip-flop synchronisers to prevent metastability from asynchronous encoder edges:

always @(posedge clk) begin
    a1 <= ui_in[0]; a2 <= a1;
    b1 <= ui_in[1]; b2 <= b1;
end
wire A = a2, B = b2;

Decoding works by comparing the current {A,B} state to the previous one. All four forward transitions (00→01→11→10→00) increment the counter; the four reverse transitions decrement it. Any other transition — including illegal states from noise — does nothing.

wire forward = (prevState==2'b00 && currentState==2'b01) ||
               (prevState==2'b01 && currentState==2'b11) ||
               (prevState==2'b11 && currentState==2'b10) ||
               (prevState==2'b10 && currentState==2'b00);

The count is 16 bits internally but 15 bits are exposed on the output pins: count[6:0] on uo_out[6:0] and count[14:7] on uio_out[7:0], with uo_out[7] carrying the direction flag. DIR reflects the last step direction, not a sign bit — as soon as the count starts decreasing, DIR goes low regardless of the absolute count value.

The design is 81 lines of Verilog. The GitHub Actions workflow runs it through LibreLane automatically on every push to produce the GDS files.

On Tiny Tapeout

Getting a chip designed used to mean either working at a company with a fab relationship, or paying tens of thousands of pounds for a private run. Tiny Tapeout batches many small designs onto a single die, splitting the cost. The SKY130 PDK is fully open-source. For a design this size the economics are accessible in a way they simply weren’t a few years ago.

What’s next

The chip should arrive around August 20262. I’ll test it with a physical encoder, check the count and direction outputs against a software implementation, and write up the results — including whether it actually works.

1

https://github.com/jakedrew/ttsky-verilog-qei

2

https://www.tinytapeout.com/chips/