Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CORDIC Processor — Pipelined VHDL Implementation

Fully pipelined, multi-computation CORDIC core in VHDL-2008.
Supports rotation and vectoring modes, verified with Python-generated test vectors and simulated with GHDL.


Table of Contents


Overview

This project implements a CORDIC (COordinate Rotation DIgital Computer) algorithm in VHDL-2008, structured as a true synchronous pipeline.
It computes trigonometric and hyperbolic functions using only shifts and additions — no multipliers required in the iteration kernel.

Two operating modes are supported:

Mode mode pin Function
Rotation '0' Rotates input vector (x1, y1) by angle β
Vectoring '1' Computes magnitude and phase of (x1, y1)

Key design properties:

  • Pure pipeline — no FSM, no handshake stalls
  • One new computation can be launched every clock cycle
  • Up to N_ITER computations in-flight simultaneously
  • CORDIC gain compensation (K ≈ 0.6073) applied in rotation mode
  • Angle pre-folding into [−π/2, π/2] convergence domain
  • Self-checking testbench with configurable tolerance thresholds

Architecture

                ┌──────────────────────────────────────────────────────┐
  x1, y1, β ──>│  cordic.vhd  (top-level + K pre-scaler)              │
  mode, start  │                                                        │
               │   ┌─────────────────────────────────────────────────┐ │
               │   │  cordic_processor.vhd  (pipeline controller)    │ │
               │   │                                                  │ │
               │   │  Stage 0 ──> kernel_0 ──> kernel_1 ──> ... ──>  │ │
               │   │   (DFF)      (DFF)         (DFF)       kernel_N  │ │
               │   │                                                  │ │
               │   │  valid_sr: start │ sr(0) │ ... │ sr(N) = done   │ │
               │   └─────────────────────────────────────────────────┘ │
               │                                                        │
  x2, y2, z2 <──────────────────────────────────────────────────────── │
  done         └──────────────────────────────────────────────────────┘

Each cordic_kernel performs one CORDIC micro-rotation:

x_{i+1} = x_i − d_i · y_i · 2^{−i}
y_{i+1} = y_i + d_i · x_i · 2^{−i}
z_{i+1} = z_i − d_i · atan(2^{−i})

where d_i = +1 or −1 depending on the mode and the sign of z_i (rotation) or y_i (vectoring).


File Structure

.
├── src/
│   ├── cordic.vhd               # Top-level wrapper (K pre-scaler + port map)
│   ├── cordic_processor.vhd     # Pipeline controller + ATAN ROM + valid SR
│   └── cordic_kernel.vhd        # Single CORDIC micro-rotation stage (DFF)
├── tb/
│   └── cordic_tb_with_file.vhd  # Self-checking testbench (file-driven)
├── python/
│   └── cordic_testdata_gen.py   # Reference vector generator
├── work/
│   ├── build/                   # GHDL compiled objects (generated)
│   ├── data/                    # Test vectors (generated)
│   └── waveform/                # VCD output (generated)
└── Makefile

Generics

Generic Entity Default Description
N_BITS_VECTOR all 32 Data path width for X and Y (bits)
N_BITS_ANGLE all 18 Angle accumulator width (bits)
N_ITER cordic, cordic_processor 15 Pipeline depth (CORDIC iterations)
CLK_PERIOD testbench 20 Testbench slow-clock half-period (ns)
DATA_FILE_M0 testbench Absolute path to Mode 0 test vector file
DATA_FILE_M1 testbench Absolute path to Mode 1 test vector file

Signal Interface

cordic (top-level)

Port Direction Width Description
clk in 1 System clock
rst in 1 Synchronous active-high reset
x1 in N_BITS_VECTOR Input X (real part)
y1 in N_BITS_VECTOR Input Y (imaginary part)
mode in 1 '0' = rotation, '1' = vectoring
beta in N_BITS_ANGLE Input angle (fixed-point)
start in 1 One-cycle pulse to launch a computation
x2 out N_BITS_VECTOR+1 Output X (sign-extended)
y2 out N_BITS_VECTOR+1 Output Y (sign-extended)
z2 out N_BITS_ANGLE Output angle / phase
done out 1 Asserted for one cycle when result is valid

Angle encoding

All angles are normalised to [−π, π) and stored as signed integers where:

LSB = π / 2^(N_BITS_ANGLE − 2)

For N_BITS_ANGLE = 18: 1 LSB ≈ 1.2 × 10⁻⁵ rad ≈ 0.00069°


Pipeline Timing

Cycle:    0      1      2      3    ...  N_ITER   N_ITER+1
          │      │      │      │         │         │
start ────┤      │      │      │         │         │
          │      │      │      │         │         │
Stage 0   ╔══════╗      │      │         │         │
(DFF)     ║ latch║      │      │         │         │
          ╚══════╝      │      │         │         │
Kernel 0         ╔══════╗      │         │         │
                 ║  DFF ║      │         │         │
                 ╚══════╝      │         │         │
Kernel 1                ╔══════╗         │         │
                        ║  DFF ║         │         │
                        ╚══════╝         │         │
...                                      │         │
Kernel N-1                         ╔═════╗         │
                                   ║ DFF ║         │
                                   ╚═════╝         │
done ────────────────────────────────────────────> ┤
x2/y2/z2 valid ──────────────────────────────────> ┤

Total latency = N_ITER + 1 clock cycles from start to done.
At N_ITER = 15: 16 cycles.


Getting Started

Prerequisites

Tool Version tested Purpose
GHDL ≥ 3.0 VHDL simulation
GTKWave ≥ 3.3 Waveform viewer
Python ≥ 3.8 Test vector generation
GNU Make any Build automation
Git Bash Windows only Shell environment

Windows note: GHDL on Windows uses the mcode backend and does not produce a standalone executable. The Makefile uses ghdl -r for simulation and cygpath -m for path conversion.

Quick Start

# Clone the repository
git clone https://github.com/myotochie/cordic.git
cd cordic

# Generate test vectors, compile, elaborate, and simulate
make run

# Open the waveform (requires GTKWave)
make view_waveform

Makefile Targets

Target Description
make run Full flow: setup → generate → compile → simulate (default)
make setup Create work/ directory tree
make generate_data Run Python script to produce test vectors
make compile Analyse and elaborate VHDL sources with GHDL
make view_waveform Open wave.vcd in GTKWave
make clean Remove all generated files under work/
make rebuild clean + run
make paths Print resolved POSIX and Windows paths (debug)

Key Makefile parameters (edit at the top of Makefile):

N_SAMPLES   := 100    # Number of test vectors per mode
CLK_PERIOD  := 20     # Testbench slow-clock half-period (ns)
STOP_TIME   := 60000ns

Simulation Flow

python cordic_testdata_gen.py
        │
        ├── work/data/cordic_m0_testdata.txt  (rotation vectors)
        └── work/data/cordic_m1_testdata.txt  (vectoring vectors)
                │
                ▼
        ghdl -a  (analyse sources)
        ghdl -e  (elaborate, with -g overrides)
        ghdl -r  (simulate → wave.vcd + report)
                │
                ▼
        cordic_tb_with_file.vhd
          ├── MODE 0: checks |x_got − x_ref| ≤ 50  and  |y_got − y_ref| ≤ 50
          └── MODE 1: checks |z_got − z_ref| ≤ 40
                │
                ▼
        report "Simulation finished. Total lines: N, Total errors: E"

A successful run produces zero warnings and ends with:

cordic_tb_with_file.vhd:...: report "Finished MODE 0"
cordic_tb_with_file.vhd:...: report "Simulation finished. Total lines: 799, Total errors: 0"
cordic_tb_with_file.vhd:...: report "Finished MODE 1"
cordic_tb_with_file.vhd:...: report "Simulation finished. Total lines: 799, Total errors: 0"

Test Data Format

Generated by python/cordic_testdata_gen.py.
All values are signed integers in the fixed-point encoding of the DUT.

cordic_m0_testdata.txt — rotation mode (5 columns):

xi  yi  beta  xo_ref  yo_ref

cordic_m1_testdata.txt — vectoring mode (6 columns):

xi  yi  beta  xo_ref  yo_ref  zo_ref

Known Limitations

  • The cordic.vhd input pre-processor is combinatorial — glitches on mode, x1, or y1 propagate immediately to the processor inputs. This is harmless as long as inputs are stable before start is asserted.
  • The cordic_kernel output registers have no reset. The pipeline guarantees that ena is never asserted before valid data has propagated, so uninitialised register values never reach the outputs.
  • Only the mcode backend of GHDL has been tested (Windows). On Linux/macOS with the GCC or LLVM backend, ghdl -r may produce a native executable; the Makefile's ghdl -r invocation remains valid in all cases.

Documentation

Each VHDL source file is commented in Doxygen format.
To generate HTML documentation:

doxygen -g                         # Generate default Doxyfile
# Edit Doxyfile: set OPTIMIZE_OUTPUT_VHDL = YES
#                set INPUT = src/ tb/
doxygen Doxyfile
# Open html/index.html

About

RTL implementation of a fully pipelined CORDIC processor(COrdinate Rotation Digital Computer) in VHDL-2008 with rotation/vectoring modes and automated verification flow

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages