Commit 441147e0 authored by Nathan Pittet's avatar Nathan Pittet

Single-file cordic fixing most of the quirks of the previous implementation with testbench.

parent d49f61cb
......@@ -6,6 +6,7 @@ files = ["cordic_init.vhd",
"gc_pipelined_fir_filter.vhd",
"gc_cordic_pkg.vhd",
"gc_cordic.vhd",
"gc_cordic_top.vhd",
"gc_dsp_pkg.vhd",
"gc_iq_demodulator.vhd",
"gc_iq_modulator.vhd",
......
......@@ -29,6 +29,7 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
package gc_cordic_pkg is
......@@ -108,6 +109,8 @@ package gc_cordic_pkg is
constant c_FSDegMinus180HD : signed(31 downto 0) := X"80000000";
constant c_FSDegZeroHD : signed(31 downto 0) := X"00000000";
function f_compute_an(nbits : integer) return std_logic_vector;
-- Cordic Sequencer Iteration Constants
constant c_CirIter : std_logic_vector(4 downto 0) := '0'&X"D";
constant c_LinIter : std_logic_vector(4 downto 0) := '0'&X"F";
......@@ -157,6 +160,18 @@ end package;
package body gc_cordic_pkg is
function f_compute_an(nbits : integer) return std_logic_vector is
variable v_an : real := 1.0;
variable v_ret : std_logic_vector(nbits-1 downto 0);
begin
for i in 0 to nbits-1 loop
v_an := v_an * sqrt(1.0+2.0**(-2*i));
end loop;
v_ret := std_logic_vector(to_signed(integer((1.0/v_an)*(2.0**(nbits-1))), nbits));
return v_ret;
end function f_compute_an;
procedure f_limit_subtract
(use_limiter : boolean;
a, b : in signed;
......@@ -166,7 +181,7 @@ package body gc_cordic_pkg is
constant c_min_val : signed(o'range) := ('1', others => '0');
variable l_sum : signed(O'length downto 0) := (others => '0');
begin
l_sum := resize(a, o'length+1) - resize(b, o'length-1);
l_sum := a(a'left)&a - b;
if not use_limiter then
o := l_sum(o'range);
......@@ -193,9 +208,9 @@ package body gc_cordic_pkg is
lim : out std_logic) is
constant c_max_val : signed(o'range) := ('0', others => '1');
constant c_min_val : signed(o'range) := ('1', others => '0');
variable l_sum : signed(O'length downto 0) := (others => '0');
variable l_sum : signed(o'length downto 0) := (others => '0');
begin
l_sum := resize(a, o'length+1) + resize(b, o'length-1);
l_sum := a(a'left)&a + b;
if not use_limiter then
o := l_sum(o'range);
......@@ -225,7 +240,7 @@ package body gc_cordic_pkg is
if x = c_min_val and use_limiter then
return c_max_val;
else
return not x (x'length-1 downto 0) + 1;
return not x(x'length-1 downto 0)+1;
end if;
else
return x;
......
This diff is collapsed.
......@@ -21,4 +21,5 @@ modules = {
files = [
"main.sv",
"gc_cordic_tb.vhd"
]
import matplotlib.pyplot as plt
import pandas as pd
def main():
filename = "res.txt"
data = pd.read_csv(filename, header=None, names=["ix", "iy", "iz","ox", "oy", "oz", "ex", "ey", "ez", "mode", "submode"])
data["mode"][data["mode"] == 0] = "vector"
data["mode"][data["mode"] == 1] = "rotate"
data["submode"][data["submode"] == 0] = "circular"
data["submode"][data["submode"] == 1] = "linear"
data.insert(len(data.columns), "err_x",abs(data["ox"]-data["ex"]))
data.insert(len(data.columns), "err_y",abs(data["oy"]-data["ey"]))
data.insert(len(data.columns), "err_z",abs(data["oz"]-data["ez"]))
print(data)
rotcirc = data[data["mode"] == "rotate"]
rotcirc = rotcirc[rotcirc["submode"] == "circular"]
rotlinear = data[data["mode"] == "rotate"]
rotlinear = rotlinear[rotlinear["submode"] == "linear"]
vectcirc = data[data["mode"] == "vector"]
vectcirc = vectcirc[vectcirc["submode"] == "circular"]
vectlinear = data[data["mode"] == "vector"]
vectlinear = vectlinear[vectlinear["submode"] == "linear"]
print(rotcirc )
print(rotlinear )
print(vectcirc )
print(vectlinear )
# How is error defined ?
# rotate/Circular -> 2 errors, xo and yo
# rotate/linear -> 2 errors, x and y
# vector/circular -> 2 errors, x and z
# vector/linear -> 2 errors, x and z
import numpy as np
fig = plt.figure()
# syntax for 3-D projection
ax = plt.axes(projection ='3d')
# defining axes
x = vectcirc["ix"]
y = vectcirc["iy"]
z = vectcirc["iz"]
err_x = vectcirc["err_x"]
err_y = vectcirc["err_y"]
err_z = vectcirc["err_z"]
plt.subplot(4,3,1)
plt.plot(x, err_x, 'x')
plt.plot(y, err_x, 'x')
plt.plot(z, err_x, 'x')
#plt.legend(["errx = f(x)", "errx = f(y)", "errx = f(z)"])
plt.title("vect/circle : magnitude error")
plt.subplot(4,3,2)
plt.plot(x, err_y, 'x')
plt.plot(y, err_y, 'x')
plt.plot(z, err_y, 'x')
#plt.legend(["erry = f(x)", "erry = f(y)", "erry = f(z)"])
plt.title("vector/circle")
plt.subplot(4,3,3)
plt.plot(x, err_z, 'x')
plt.plot(y, err_z, 'x')
plt.plot(z, err_z, 'x')
#plt.legend(["errz = f(x)", "errz = f(y)", "errz = f(z)"])
plt.title("vector/circle : angle error")
x = rotcirc["ix"]
y = rotcirc["iy"]
z = rotcirc["iz"]
err_x = rotcirc["err_x"]
err_y = rotcirc["err_y"]
err_z = rotcirc["err_z"]
plt.subplot(4,3,4)
plt.plot(x, err_x, 'x')
plt.plot(y, err_x, 'x')
plt.plot(z, err_x, 'x')
#plt.legend(["errx = f(x)", "errx = f(y)", "errx = f(z)"])
plt.title("rotate/circle")
plt.subplot(4,3,5)
plt.plot(x, err_y, 'x')
plt.plot(y, err_y, 'x')
plt.plot(z, err_y, 'x')
#plt.legend(["erry = f(x)", "erry = f(y)", "erry = f(z)"])
plt.title("rotate/circle")
plt.subplot(4,3,6)
plt.plot(x, err_z, 'x')
plt.plot(y, err_z, 'x')
plt.plot(z, err_z, 'x')
#plt.legend(["errz = f(x)", "errz = f(y)", "errz = f(z)"])
plt.title("rotate/circle")
x = rotlinear["ix"]
y = rotlinear["iy"]
z = rotlinear["iz"]
err_x = rotlinear["err_x"]
err_y = rotlinear["err_y"]
err_z = rotlinear["err_z"]
plt.subplot(4,3,7)
plt.plot(x, err_x, 'x')
plt.plot(y, err_x, 'x')
plt.plot(z, err_x, 'x')
#plt.legend(["errx = f(x)", "errx = f(y)", "errx = f(z)"])
plt.title("rotate/linear")
plt.subplot(4,3,8)
plt.plot(x, err_y, 'x')
plt.plot(y, err_y, 'x')
plt.plot(z, err_y, 'x')
#plt.legend(["erry = f(x)", "erry = f(y)", "erry = f(z)"])
plt.title("rotate/linear")
plt.subplot(4,3,9)
plt.plot(x, err_z, 'x')
plt.plot(y, err_z, 'x')
plt.plot(z, err_z, 'x')
#plt.legend(["errz = f(x)", "errz = f(y)", "errz = f(z)"])
plt.title("rotate/linear")
x = vectlinear["ix"]
y = vectlinear["iy"]
z = vectlinear["iz"]
xy = vectlinear["iy"]/vectlinear["ix"]
err_x = vectlinear["err_x"]
err_y = vectlinear["err_y"]
err_z = vectlinear["err_z"]
plt.subplot(4,3,10)
plt.plot(xy, err_x, 'x')
plt.plot(xy, err_y, 'x')
plt.plot(xy, err_z, 'x')
#plt.legend(["errx = f(y/x)", "erry = f(y/x)", "errz = f(y/x)"])
plt.title("vector/linear: ratio error = f(ratio)")
plt.subplot(4,3,11)
plt.plot(x, err_y, 'x')
plt.plot(y, err_y, 'x')
plt.plot(z, err_y, 'x')
#plt.legend(["erry = f(x)", "erry = f(y)", "erry = f(z)"])
plt.title("vector/linear")
plt.subplot(4,3,12)
plt.plot(x, err_z, 'x')
plt.plot(y, err_z, 'x')
plt.plot(z, err_z, 'x')
#plt.legend(["errz = f(x)", "errz = f(y)", "errz = f(z)"])
plt.title("vector/linear: ratio error")
plt.show()
if __name__ == "__main__":
main()
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment