cordic_alu Source

Sine, cosine and angles from nothing but shifts and adds.

tt_um_aariv_cordic_alu is a small Tiny Tapeout design for the GF180MCU shuttle. One eight clock CORDIC engine rotates and measures vectors. Next to it sit a saturating accumulator and a pseudo random generator with a CRC. This page runs the same logic in your browser, one clock edge at a time.

Status. This is an AI assisted reference design. Hack Club ASIC does not accept AI written chip code or write ups, so it is not an eligible entry for that program. It has not been taped out and it has not been run on hardware.

Generic gates after Yosys
835
Clocks per CORDIC result
8
Hardware multipliers
0
Clock cycles checked against Verilog
320,028
A vector rotating around the unit circle in eight CORDIC steps
Stage 0 of 8

Workbench

Flip the input switches, pulse START and step the clock. Everything below is computed by the JavaScript twin of the Verilog, register for register.

Input pins

ui_in selects the opcode (bits 7 and 6) and a signed 6 bit operand A (bits 5 to 0).

uio_in[3:0] are control inputs. uio_in[7:4] are outputs, so they have no switch.

opcode 00 rotate, A = 0

Clock

Try one

Clock cycle 0

Unit circle

CORDIC vector position on the unit circle
Idle. Pulse START in rotate or vector mode to see the eight micro-rotations.
  • Vector now
  • Earlier stages
  • Target angle
  • Start length 0.607

    Logic analyzer

    Download VCD

    The newest clock cycle is on the right. Values are hexadecimal; x_reg and y_reg are 11 bit two's complement, z_reg is 12 bit.

    Registers and outputs

    x_reg
    000
    y_reg
    000
    z_reg
    000
    iter
    0
    acc
    00
    lfsr
    01
    crc
    00
    view
    mac
    uo_out
    00
    uio_out
    20
    • BUSY
    • ZERO
    • OVERFLOW
    • SIGN

    What the numbers mean

    Reset state. The accumulator is zero.

    How the datapath works

    CORDIC turns a rotation into a staircase of tiny, fixed turns. Each turn is a shift and an add, so the chip never needs a multiplier.

    The engine keeps three registers. x and y hold a vector, and z holds the angle still left to turn. On stage i the vector turns by plus or minus atan(2^-i). A turn of that size equals x shifted right by i bits, added to or taken from y, and the other way round for x. A small lookup table holds the eight angles.

    In rotation mode the sign of z picks the turn direction, and z shrinks toward zero. Starting from x = 0.607 cancels the length growth of 1.6467 that the eight turns add, so the result is cosine in x and sine in y.

    In vectoring mode the sign of y picks the direction and the engine drives y to zero. Then z holds the angle of the input and x holds its length times 1.6467. A vector in the left half plane is first turned by 90 degrees so the loop converges.

    One CORDIC stage. Registers x, y and z feed three add or subtract units. The x and y units also take each other's value shifted right by i, and the z unit takes the angle table entry. x y z x -/+ (y >> i) barrel shift of y y +/- (x >> i) barrel shift of x z -/+ atan[i] angle table 8 entry atan table x' y' z'
    One micro-rotation. The copper lines cross because each of x and y is corrected by the shifted value of the other. The direction d is the sign of z in rotation mode and the sign of y in vectoring mode. x', y' and z' are written back to the registers on the next clock edge.
    The four operations. Operand A is ui_in[5:0], a signed 6 bit value.
    ui_in[7:6]OperationHow to run ituo_out
    00RotateA is a signed angle in units of pi/64, from -32 (minus 90 degrees) to 31 (plus 87.2 degrees). Rising edge on START.cos in Q1.7. RSEL = 1 shows sin. Saturates at plus 127 and minus 128.
    01VectorSTART with MODE 0 loads x = A. START with MODE 1 loads y = A and runs.length times 1.6467 (whole number). RSEL = 1 shows the angle, 128 counts per half turn.
    10Saturating MACSTART adds A, or 3A when GAIN3 = 1. START with MODE 1 clears.8 bit signed accumulator. OVERFLOW marks a clamped add.
    11PRBS and CRCMODE 0 free runs a Galois LFSR, START seeds it with 01 and A. MODE 1 with START feeds A to a CRC-8, RSEL = 1 clears it.LFSR state, or CRC after a feed.

    Measured accuracy

    These figures are recomputed in this browser from the simulator every time the page loads, against Math.cos, Math.sin and Math.atan2.

    Worst cosine error
    1.73 LSB
    Worst sine error
    1.45 LSB
    Worst length error
    1.07 counts
    Worst angle error, length 8 or more
    1.15 counts

    One LSB is 1/128, about 0.8 percent of full scale. One angle count is 1.4 degrees. Vectors shorter than 4 units lose precision because the registers hold only 3 fractional bits there, with errors up to about 6 counts.

    Floorplan sketch

    The tile is 340 by 160 micrometres. Rectangles below are drawn with area proportional to each module's generic gate count from Yosys. This is a sketch of relative size. It is not a placed and routed layout.

    Relative size of the four Verilog modules inside a 340 by 160 micrometre tile
    Hover, tap or focus a block for its gate count.
    Yosys 0.70, generic gates and flip-flops
    ModuleCellsFlip-flopsLogic

    The Tiny Tapeout GDS workflow mapped the design to 894 GF180MCU cells with 19,575 square micrometres of cell area, inside a core of 51,967 square micrometres, so it does fit one tile. The rectangles above use the generic counts from the table, so they show relative size only.

    Pinout

    The tile has the standard Tiny Tapeout interface. Pin colour follows the live pin state in the workbench. Select a pin for its role.

    Select a pin, or step through them.
    Pin roles
    PinDirectionRole

    What has been checked, and what has not

    Done

    • The Verilog compiles clean under Icarus Verilog 13 with warnings on, and synthesizes in Yosys 0.70.
    • A replay bench runs the Verilog and this page's JavaScript twin through the same stimulus. Every output and every internal register matched after every clock edge for 320,028 cycles, over two random seeds plus directed sweeps of every operation.
    • The comparison was shown to fail when either side is changed by one constant, so a pass means something.
    • Accuracy limits above are asserted by the test suite, not only displayed.
    • The Tiny Tapeout GDS workflow built the layout in GF180MCU cells, the precheck reported 0 DRC violations and the gate-level test passed.

    Not done

    • No tapeout, and no person has reviewed the layout image. The workflow's own Pages viewer job fails because this site is served from the main branch.
    • No test on an FPGA or with a logic analyzer. The plan is to load the Verilog on an FPGA board, wire ui_in and uio_in to switches, and capture uo_out and uio_out on a logic analyzer while stepping through the four operations in the table above.
    • The fpga workflow was not checked. The cocotb tests in test/test.py pass under Icarus Verilog, locally and in the test workflow, and they check against math rather than the JavaScript twin.
    • No write up has been published. WRITEUP.md only collects measured facts for a person to write from.