This repository contains a synthesizable, 16-bit, 16-stage pipelined CORDIC (Coordinate Rotation Digital Computer) engine written in Verilog. It's designed to calculate the sine and cosine of a given input angle with high throughput, making it ideal for applications in Digital Signal Processing (DSP), communications, and real-time control systems.
The primary advantage of the CORDIC algorithm is its ability to compute trigonometric functions using only simple hardware components: adders, subtractors, and bit-shifters. It completely avoids the need for complex and resource-intensive multipliers.
CORDIC is an elegant algorithm that calculates trigonometric and other functions by performing a series of micro-rotations.
Imagine a vector on a 2D plane. To find the sine and cosine of an angle (x=1, y=0)) and rotates it by the target angle
Instead of performing one large, complex rotation, CORDIC performs a sequence of smaller, progressively finer rotations. The "trick" is that the angles of these micro-rotations are chosen to be
The core iterative equations for the rotation mode are:
$x_{i+1} = x_i - d_i \cdot y_i \cdot 2^{-i}$
$y_{i+1} = y_i + d_i \cdot x_i \cdot 2^{-i}$
$z_{i+1} = z_i - d_i \cdot \arctan(2^{-i})$
Where:
-
$x_i, y_i$ are the vector coordinates at iteration$i$ . -
$z_i$ is the remaining angle to rotate. -
$d_i$ is the direction of rotation (+1 or -1), chosen at each step to make the remaining angle$z$ approach zero.
- Pipelined Architecture: A fully unrolled 16-stage pipeline allows it to accept a new angle on every clock cycle after an initial 16-cycle latency. This results in a very high throughput of 1 result/cycle with no FSM bottlenecks.
- Multiplier-less Design: True to the CORDIC algorithm, the datapath contains no hardware multipliers, saving significant hardware resources.
- Fixed-Point Arithmetic: Uses a 16-bit signed Q2.14 fixed-point format for all calculations, providing a good balance between precision and hardware cost.
- High Throughput: Ideal for streaming data applications in DSP and software-defined radio (SDR).
- Synthesizable: The code is written in a synthesizable subset of Verilog, ready for implementation on FPGAs or ASICs.
- Comprehensive Testbench: Includes a self-checking testbench that verifies the output against expected values for several angles.
The module is composed of three main parts:
-
Angle Look-Up Table (LUT): A small, hardcoded ROM that stores the pre-calculated
$\arctan(2^{-i})$ constants required for each iteration. -
Pipelined Datapath: This is the core of the engine. It consists of 16 physical stages, where each stage contains:
- Two shifters (for the
$\cdot 2^{-i}$ operation). - Three adders/subtractors (to calculate the next
$x, y,$ and$z$ ). - Pipeline registers to hold the results between stages.
- Two shifters (for the
This implementation uses a Q2.14 signed fixed-point format. For a 16-bit number, this means:
- 1 bit for the sign (S)
- 1 bit for the integer part (I)
- 14 bits for the fractional part (F)
S . I . FFFFFFFFFFFFFF
b15 b14 b13 ... b0
This format can represent numbers from -2.0 to +1.999...
To work with this format, input angles in degrees must be scaled. The range from -90Β° to +90Β° is mapped to the range -1.0 to +1.0 in the Q2.14 format. The scaling factor is
- +90Β° β
16384(which is 1.0 in Q2.14) - +45Β° β
8192(which is 0.5 in Q2.14) - -30Β° β
-5461
The testbench (tb_cordic.v) handles this conversion automatically.
The series of micro-rotations in the CORDIC algorithm scales the magnitude of the initial vector by a constant gain factor,
This implementation starts with an initial vector of (x=1, y=0). Therefore, the final outputs are not
-
Pre-scaling: Starting with an initial vector of
$(1/K, 0) \approx (0.60725, 0)$ . -
Post-scaling: Dividing the final
$x$ and$y$ outputs by the gain$K$ .
The testbench output reflects this uncorrected gain. For an input of 0Β°, the expected cosine is 1.0, but the DUT output is ~0.6073, which is the reciprocal of the gain (
.
βββ cordic.v # The synthesizable CORDIC core module.
βββ tb_cordic.v # The testbench for simulating and verifying the core.
βββ schematics.md # Architectural diagrams and datapath schematics.
You can simulate this project using open-source tools like Icarus Verilog and view the waveforms with GTKWave.
Ensure you have Icarus Verilog and GTKWave installed on your system.
-
Compile the Verilog files: Open your terminal in the project directory and run the compilation command:
iverilog -o cordic_tb.vvp cordic.v tb_cordic.v
-
Run the simulation: Execute the compiled design:
vvp cordic_tb.vvp
The testbench is self-checking and will print the results of each test to the console. The output shows the DUT's raw integer and scaled fixed-point values alongside the mathematically expected sine/cosine values. Note the gain difference as explained above.
================== PIPELINED CORDIC TEST START ==================
-----------------------------------------------------
Received output for angle index: 0
Angle tested: 0.000000 degrees
DUT Output (int): cos= 16385, sin= -2
DUT Output (real): cos=1.000061, sin=-0.000122
Expected (real): cos=1.000000, sin=0.000000
-----------------------------------------------------
Received output for angle index: 1
Angle tested: 30.000000 degrees
DUT Output (int): cos= 14193, sin= 8192
DUT Output (real): cos=0.866272, sin=0.500000
Expected (real): cos=0.866025, sin=0.500000
-----------------------------------------------------
Received output for angle index: 2
Angle tested: 45.000000 degrees
DUT Output (int): cos= 11587, sin= 11586
DUT Output (real): cos=0.707214, sin=0.707153
Expected (real): cos=0.707107, sin=0.707107
-----------------------------------------------------
Received output for angle index: 3
Angle tested: 60.000000 degrees
DUT Output (int): cos= 8190, sin= 14193
DUT Output (real): cos=0.499878, sin=0.866272
Expected (real): cos=0.500000, sin=0.866025
-----------------------------------------------------
Received output for angle index: 4
Angle tested: 90.000000 degrees
DUT Output (int): cos= -4, sin= 16385
DUT Output (real): cos=-0.000244, sin=1.000061
Expected (real): cos=0.000000, sin=1.000000
-----------------------------------------------------
Received output for angle index: 5
Angle tested: -30.000000 degrees
DUT Output (int): cos= 14193, sin= -8190
DUT Output (real): cos=0.866272, sin=-0.499878
Expected (real): cos=0.866025, sin=-0.500000
-----------------------------------------------------
Received output for angle index: 6
Angle tested: -90.000000 degrees
DUT Output (int): cos= -6, sin=-16385
DUT Output (real): cos=-0.000366, sin=-1.000061
Expected (real): cos=0.000000, sin=-1.000000
================== PIPELINED CORDIC TEST END ==================