OpenCores
URL https://opencores.org/ocsvn/cordic_atan_iq/cordic_atan_iq/trunk

Subversion Repositories cordic_atan_iq

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 7 to Rev 8
    Reverse comparison

Rev 7 → Rev 8

/cordic_atan_iq/AuxClasses.sv
0,0 → 1,46
`ifndef _AuxClasses_
`define _AuxClasses_
 
package AuxClassesPkg;
const real PI = 3.1415926535897932384626433832795;
const int V_MAX = {{3{1'b0}}, {29{1'b1}}};
const int V_MIN = {{3{1'b1}}, {29{1'b0}}};
// const int V_MAX = {{4{1'b0}}, {28{1'b1}}};
// const int V_MIN = {{4{1'b1}}, {28{1'b0}}};
 
class IQClass;
int I, Q;
function new(int I, int Q);
this.I = I;
this.Q = Q;
endfunction
endclass :IQClass
class IQArrayList;
IQClass data[$];
function new();
data = {};
endfunction
function void push_back(int I, int Q);
IQClass iq = new(I, Q);
data.push_back(iq);
endfunction
function int size();
return data.size;
endfunction
function string ToString();
return "";
endfunction
endclass :IQArrayList
 
endpackage :AuxClassesPkg
 
`endif
/cordic_atan_iq/AuxFunc.sv
0,0 → 1,89
`ifndef _AuxPkg_
`define _AuxPkg_
`include "AuxClasses.sv"
 
package AuxFuncPkg;
import AuxClassesPkg::*;
export AuxClassesPkg::*;
function automatic int atan_iq_int(int IS, int QS);
if (IS == 0)
if (QS > 0)
return 2**30; // 90
else if (QS < 0)
return -(2**30); // -90
else
return 0;
else if (QS == 0)
if (IS < 0)
return 1<<31; // -180
else
return 0;
else if (IS < 0)
if (QS > 0)
return int'(($atan(real'(QS)/IS) + PI) * ((2.0**31) / PI));
else
return int'(($atan(real'(QS)/IS) - PI) * ((2.0**31) / PI));
else
return int'($atan(real'(QS)/IS) * ((2.0**31) / PI));
endfunction
function automatic real int_to_deg(int angle);
return real'(angle) / 2.0**30 * 90.0;
endfunction
function automatic int delta(int ref_angle, int angle);
return angle - ref_angle;
endfunction
function automatic real rel_pct(int ref_angle, int angle);
int d = delta(ref_angle, angle);
if (d < 0) d = -d;
if (ref_angle == 0)
if (d == 0)
return 0;
else
return 100;
else
return real'(d) / real'(ref_angle) * 100.0;
endfunction
function automatic IQArrayList GenIQ(int POINTS = 8);
IQArrayList v = new;
// 135...45 deg
for (int i = -POINTS; i < POINTS; i++)
v.push_back(i * (V_MAX / POINTS), V_MAX);
// 45...-45 deg
for (int i = POINTS; i > -POINTS; i--)
v.push_back(V_MAX, i * (V_MAX / POINTS));
// -45...-135 deg
for (int i = POINTS; i > -POINTS; i--)
v.push_back(i * (V_MAX / POINTS), V_MIN);
// -135...135 deg
for (int i = -POINTS; i < POINTS; i++)
v.push_back(V_MIN, i * (V_MAX / POINTS));
return v;
endfunction
function automatic int unsigned iabs(int value);
if (value < 0) value = -value;
return value;
endfunction
function automatic int unsigned imag(int I, int Q);
real res = int'( $sqrt(real'(I) * real'(I) + real'(Q) * real'(Q)) );
int unsigned res_uint = longint'(res);
// $display("I %d Q %d Mag %g (%d)\n", I, Q, res, res_uint);
return res_uint;
endfunction
 
endpackage :AuxFuncPkg
 
`endif
/cordic_atan_iq/atan32_table.sv
0,0 → 1,53
`ifndef _atan32_table_
`define _atan32_table_
// atan table for values 1, 1/2, 1/4, 1/8, 1/16...
// Scale: code 2^30 = 90 deg, code 0 = 0 deg
 
package ConstPkg;
 
parameter STEPS = 32;
parameter real K = 0.6072529350088813;
parameter bit [29:0] K_u30 = 30'h26dd3b6a;
parameter bit [31:0] K_u32 = 32'h9b74eda8;
// for sin and cos start calculation from vector {K_u30, 0}
// modulus of vector {I, Q} = (coe_abs * K_u32) >> 32
// last table value dont use
 
parameter bit signed [31:0] atan_table[STEPS] = '{
32'sh20000000, // tan = 1/2^1 = 1/2
32'sh12e4051e, // tan = 1/2^2 = 1/4
32'sh09fb385b, // tan = 1/2^3 = 1/8
32'sh051111d4, // tan = 1/2^4 = 1/16
32'sh028b0d43, // tan = 1/2^5 = 1/32
32'sh0145d7e1, // tan = 1/2^6 = 1/64
32'sh00a2f61e, // tan = 1/2^7 = 1/128
32'sh00517c55, // tan = 1/2^8 = 1/256
32'sh0028be53, // tan = 1/2^9 = 1/512
32'sh00145f2f, // tan = 1/2^10 = 1/1024
32'sh000a2f98, // tan = 1/2^11 = 1/2048
32'sh000517cc, // tan = 1/2^12 = 1/4096
32'sh00028be6, // tan = 1/2^13 = 1/8192
32'sh000145f3, // tan = 1/2^14 = 1/16384
32'sh0000a2fa, // tan = 1/2^15 = 1/32768
32'sh0000517d, // tan = 1/2^16 = 1/65536
32'sh000028be, // tan = 1/2^17 = 1/131072
32'sh0000145f, // tan = 1/2^18 = 1/262144
32'sh00000a30, // tan = 1/2^19 = 1/524288
32'sh00000518, // tan = 1/2^20 = 1/1048576
32'sh0000028c, // tan = 1/2^21 = 1/2097152
32'sh00000146, // tan = 1/2^22 = 1/4194304
32'sh000000a3, // tan = 1/2^23 = 1/8388608
32'sh00000051, // tan = 1/2^24 = 1/16777216
32'sh00000029, // tan = 1/2^25 = 1/33554432
32'sh00000014, // tan = 1/2^26 = 1/67108864
32'sh0000000a, // tan = 1/2^27 = 1/134217728
32'sh00000005, // tan = 1/2^28 = 1/268435456
32'sh00000003, // tan = 1/2^29 = 1/536870912
32'sh00000001, // tan = 1/2^30 = 1/1073741824
32'sh00000001, // tan = 1/2^31 = 1/2147483648
32'sh00000000 // tan = 1/2^32 = 1/4294967296
};
 
endpackage: ConstPkg
 
`endif
/cordic_atan_iq/atan32_table_gen.m
0,0 → 1,49
clc
 
i = 0;
atan_table(1) = int32(1);
 
while i == 0 || atan_table(i) ~= 0
atan_table(i+1) = int32(round(atan(1/2^i) / (pi/2) * 2^30));
i = i + 1;
end
 
k = 1;
for i=1:length(atan_table) % ?
k = k * 1 / sqrt(1 + 2^(-2 * (i-1)));
end
 
fid = fopen('atan32_table.sv', 'w');
 
fprintf(fid, '`ifndef _atan32_table_\n');
fprintf(fid, '`define _atan32_table_\n');
fprintf(fid, '// atan table for values 1, 1/2, 1/4, 1/8, 1/16...\n');
fprintf(fid, '// Scale: code 2^30 = 90 deg, code 0 = 0 deg\n\n');
 
fprintf(fid, 'package ConstPkg;\n\n');
fprintf(fid, ' parameter STEPS = %d;\n', length(atan_table));
fprintf(fid, ' parameter real K = %.16f;\n', k);
fprintf(fid, ' parameter bit [29:0] K_u30 = 30''h%08x;\n', int32(round(k * 2^30)));
fprintf(fid, ' parameter bit [31:0] K_u32 = 32''h%08x;\n', uint32(round(k * 2^32)));
fprintf(fid, '// for sin and cos start calculation from vector {K_u30, 0}\n');
fprintf(fid, '// modulus of vector {I, Q} = (coe_abs * K_u32) >> 32\n');
fprintf(fid, '// last table value dont use\n\n');
 
fprintf(fid, ' parameter bit signed [31:0] atan_table[STEPS] = ''{\n');
 
for i=1:length(atan_table)
fprintf(fid, ' 32''sh%08x', atan_table(i));
if i ~= length(atan_table)
fprintf(fid, ', // tan = 1/2^%d = 1/%d\n', i, 2^i);
else
fprintf(fid, ' // tan = 1/2^%d = 1/%d\n', i, 2^i);
fprintf(fid, ' };\n\n');
end
end
 
fprintf(fid, 'endpackage: ConstPkg\n\n');
fprintf(fid, '`endif\n');
 
fclose(fid);
 
sum(double(atan_table / 2^30))
/cordic_atan_iq/cordic_atan_abs.sv
0,0 → 1,30
`ifndef _cordic_atan_abs_
`define _cordic_atan_abs_
`include "cordic_atan_iq.sv"
 
module cordic_atan_abs(clk, IS, QS, angle, abs);
import ConstPkg::K_u32;
 
input wire clk;
input wire signed [29:0] IS, QS;
output reg signed [31:0] angle;
output reg [30:0] abs; // sqrt(I^2 + Q^2)
wire signed [31:0] angle_res;
wire [31:0] coe_radius;
cordic_atan_iq cordic_inst(.clk, .IS, .QS, .angle(angle_res), .coe_radius);
 
reg [($bits(coe_radius) + $bits(K_u32) - 1):0] abs_reg;
always_ff @(posedge clk)
abs_reg <= coe_radius * K_u32;
assign abs = abs_reg[$bits(K_u32)+:31];
always_ff @(posedge clk)
angle <= angle_res;
 
endmodule :cordic_atan_abs
 
`endif
/cordic_atan_iq/cordic_atan_abs_tb.sv
0,0 → 1,152
timeunit 1ns;
timeprecision 1ns;
 
`include "AuxFunc.sv"
`include "AuxClasses.sv"
 
module cordic_atan_abs_tb;
import AuxFuncPkg::*;
import AuxClassesPkg::*;
 
bit clk = 0;
bit signed [29:0] IS, QS;
wire signed [31:0] angle;
wire [30:0] abs;
int ang_delta_max = 0, ang_delta_min = 0;
int abs_delta_max = 0, abs_delta_min = 0;
real pct;
int i, j;
always #10ns clk++;
initial begin
repeat(10) @(posedge clk);
//Test(20_000_000, 4_000_000);
//Test(0, V_MAX);
//Test(V_MIN, 0);
// Test(V_MIN, V_MIN);
// Test(32'he0000008, 32'h1fffffff);
//Test(0, V_MIN);
Test2();
$stop(2);
end
cordic_atan_abs dut(.*);
//
task Test(bit signed [29:0] I, Q);
int atan_ref, ang_delta, abs_ref, abs_res, abs_delta;
IS = I;
QS = Q;
repeat(100) @(posedge clk);
atan_ref = atan_iq_int(int'(IS), int'(QS));
ang_delta = delta(atan_ref, angle);
pct = rel_pct(atan_ref, angle);
$display("%d {%08h, %08h}. Ref %g deg (%d), RTL A = %g deg (%d), delta %d (%g pct)", i, int'(IS), int'(QS), int_to_deg(atan_ref), atan_ref, int_to_deg(angle), angle, ang_delta, pct);
abs_ref = imag(I, Q);
abs_res = 32'(abs);
abs_delta = delta(abs_ref, abs_res);
$display("\tAbs: Ref %d, RTL %d, delta %d", abs_ref, abs_res, abs_delta);
assert (iabs(ang_delta) <= 16 && iabs(abs_delta) <= 16) else $display("ERROR!");
endtask
task Test2(int POINTS = 8192);
int atan_ref, ang_delta, abs_ref, abs_res, abs_delta;
int I, Q;
automatic bit error = 0;
// automatic IQArrayList v = GenIQ(POINTS/8);
automatic IQArrayList v = GenIQ(1024);
fork
begin
for (int i = 0; i < v.size(); i++) begin
IS = v.data[i].I;
QS = v.data[i].Q;
@(posedge clk);
end
end
begin
repeat(32+2) @(posedge clk);
for (int i = 0; i < v.size(); i++) begin
I = v.data[i].I;
Q = v.data[i].Q;
atan_ref = atan_iq_int(I, Q);
ang_delta = delta(atan_ref, angle);
if (ang_delta > ang_delta_max) ang_delta_max = ang_delta;
if (ang_delta < ang_delta_min) ang_delta_min = ang_delta;
pct = rel_pct(atan_ref, angle);
$display("%d {%08h, %08h}: Ref %g deg (%d), RTL %g deg (%d), delta %d (%g pct)", i, I, Q, int_to_deg(atan_ref), atan_ref, int_to_deg(angle), angle, ang_delta, pct);
abs_ref = imag(I, Q);
abs_res = 32'(abs);
abs_delta = delta(abs_ref, abs_res);
if (abs_delta > abs_delta_max) abs_delta_max = abs_delta;
if (abs_delta < abs_delta_min) abs_delta_min = abs_delta;
$display("\tAbs: Ref %d, RTL %d, delta %d", abs_ref, abs_res, abs_delta);
assert (iabs(ang_delta) <= 16 && iabs(abs_delta) <= 16)
else
begin
error = 1;
$display("ERROR!");
end
@(posedge clk);
end
if (error)
$display("Result: ERROR!");
else
$display("Result: OK");
end
join
$display("Calculation precision: [%d, %d] ([%g, %g] sec)", ang_delta_min, ang_delta_max, int_to_deg(ang_delta_min) * 60**2, int_to_deg(ang_delta_max) * 60**2);
$display("\tAbs: [%d, %d])", abs_delta_min, abs_delta_max);
repeat(100) @(posedge clk);
$stop(2);
endtask
//
wire [31:0][31:0] x;
wire [30:0][31:0] y;
wire [31:1][31:0] a;
genvar k;
generate for (k = 0; k < 32; k++)
begin :gen_x
assign x[k] = dut.cordic_inst.x[k];
end
endgenerate
genvar n;
generate for (n = 0; n < 31; n++)
begin :gen_y
assign y[n] = dut.cordic_inst.y[n];
end
endgenerate
genvar m;
generate for (m = 1; m < 32; m++)
begin :gen_a
assign a[m] = dut.cordic_inst.a[m];
end
endgenerate
endmodule :cordic_atan_abs_tb
/cordic_atan_iq/cordic_atan_iq.m
0,0 → 1,80
 
function [angle, isqrt] = cordic_atan_iq(IS, QS);
 
IS = int32(IS);
QS = int32(QS);
 
tg = double(QS) / double(IS);
atg = atan(tg) / pi * 180;
fprintf('Given I = %g, Q = %g, angle = %g degree\n', IS, QS, atg);
 
sign = IS < 0;
if sign
IS = -IS;
QS = -QS;
end
 
% [F Exp_I] = log2(double(IS));
% [F Exp_Q] = log2(double(QS));
%
% Exp_I
% Exp_Q
%
% E = max(Exp_I, Exp_Q) + 1;
%
% IS = int32(IS * 2^(31 - E));
% QS = int32(QS * 2^(31 - E));
 
fprintf('I = 0x%08x, Q = 0x%08x\n', IS, QS);
 
i = 0;
atan_table(1) = int32(1);
 
while i == 0 || atan_table(i) ~= 0
atan_table(i+1) = int32(2^30 * atan(1/2^i) / (pi/2));
i = i + 1;
end
 
k = 1;
for i=1:length(atan_table)
k = k * 1 / sqrt(1 + 2^(-2 * (i-1)));
end
 
x(1) = IS;
y(1) = QS;
a(1) = int32(0);
 
tg = double(y(1)) / double(x(1));
atg = atan(tg) / pi * 180;
fprintf('i = %d: x = %d, y = %d (%g deg), a = %d(%g degree)\n', 0, x(1), y(1), atg, a(1), double(a(1))/2^30 * 90);
 
for i=2:length(atan_table) % i dont use last table element
if y(i-1) > 0
x(i) = x(i-1) + y(i-1) / 2^(i-2);
y(i) = -x(i-1) / 2^(i-2) + y(i-1);
a(i) = a(i-1) - atan_table(i-1);
fprintf('i = %d: rot = %g deg, ', i-1, -double(atan_table(i-1)) / 2^30 * 90);
else
x(i) = x(i-1) - y(i-1) / 2^(i-2);
y(i) = x(i-1) / 2^(i-2) + y(i-1);
a(i) = a(i-1) + atan_table(i-1);
fprintf('i = %d: rot = %g deg, ', i-1, double(atan_table(i-1)) / 2^30 * 90);
end
tg = double(y(i)) / double(x(i));
atg = atan(tg) / pi * 180;
fprintf('x = %d, y = %d (%g deg), a = %d(%g deg)\n', x(i), y(i), atg, a(i), double(a(i))/2^30 * 90);
end
 
angle = -double(a(end))/2^30 * 90;
if sign
if angle > 0
angle = angle - 180;
else
angle = angle + 180;
end
end
 
isqrt = int32(k * double(x(end)));
 
end
/cordic_atan_iq/cordic_atan_iq.sv
0,0 → 1,87
`ifndef _cordic_atan_iq_
`define _cordic_atan_iq_
`include "atan32_table.sv"
 
// Calc delay 32 clocks
module cordic_atan_iq(clk, IS, QS, angle, coe_radius);
import ConstPkg::atan_table;
localparam STEPS = ConstPkg::STEPS;
 
input wire clk; // todo: clk_ena
input wire signed [29:0] IS, QS;
output signed [31:0] angle;
output [31:0] coe_radius; // sqrt(I^2 + Q^2) / K
wire isign;
reg isign_reg;
reg signed [31:0] x[STEPS], y[STEPS-1]; // + 2 bit for carry (sqrt(2) * (1 + k)) todo: x unsigned and increase input vector width
reg signed [31:0] a[STEPS-1:1];
assign isign = IS < 'sh0;
// rotate to working range -90..+90
always_ff @(posedge clk) begin
x[0] <= (isign) ? 32'sh0 - IS : 32'sh0 + IS;
y[0] <= (isign) ? 32'sh0 + QS : 32'sh0 - QS; // invert y sign for true result sign
isign_reg <= isign; // save rotate on 180 deg
end
always_ff @(posedge clk)
if (y[0] > 'sh0)
begin
x[1] <= x[0] + y[0];
y[1] <= y[0] - x[0];
if (isign_reg)
a[1] <= signed'({1'b0, {31{1'b1}}}) - (atan_table[0] - 1'b1); // rotate 180 - 45 deg
else
a[1] <= -atan_table[0]; // rotate -45 deg
end
else
begin
x[1] <= x[0] - y[0];
y[1] <= y[0] + x[0];
if (isign_reg)
a[1] <= signed'({1'b1, {31{1'b0}}}) + atan_table[0]; // rotate -180 + 45 deg
else
a[1] <= atan_table[0]; // rotate +45 deg
end
genvar i;
generate for(i = 2; i < STEPS-1; i++)
begin :gen
always_ff @(posedge clk)
if (y[i-1] > 'sh0)
begin
x[i] <= x[i-1] + (y[i-1] >>> (i - 1));
y[i] <= y[i-1] - (x[i-1] >>> (i - 1));
a[i] <= a[i-1] - atan_table[i-1];
end
else
begin
x[i] <= x[i-1] - (y[i-1] >>> (i - 1));
y[i] <= y[i-1] + (x[i-1] >>> (i - 1));
a[i] <= a[i-1] + atan_table[i-1];
end
end
endgenerate
always_ff @(posedge clk)
if (y[STEPS-2] > 'sh0)
begin
x[STEPS-1] <= x[STEPS-2] + (y[STEPS-2] >>> (STEPS-2));
a[STEPS-1] <= a[STEPS-2] - atan_table[STEPS-2];
end
else
begin
x[STEPS-1] <= x[STEPS-2] - (y[STEPS-2] >>> (STEPS-2));
a[STEPS-1] <= a[STEPS-2] + atan_table[STEPS-2];
end
assign angle = a[STEPS-1];
assign coe_radius = x[STEPS-1];
 
endmodule : cordic_atan_iq
 
`endif
/cordic_atan_iq/cordic_atan_iq_tb.sv
0,0 → 1,151
timeunit 1ns;
timeprecision 1ns;
 
`include "AuxFunc.sv"
`include "AuxClasses.sv"
`include "atan32_table.sv"
 
module cordic_atan_iq_tb;
import AuxFuncPkg::*;
import AuxClassesPkg::*;
 
bit clk = 0;
bit signed [29:0] IS, QS;
wire signed [31:0] angle;
wire [31:0] coe_radius;
int ang_delta_max = 0, ang_delta_min = 0;
int abs_delta_max = 0, abs_delta_min = 0;
real pct;
int i, j;
always #10ns clk++;
initial begin
repeat(10) @(posedge clk);
//Test(20_000_000, 4_000_000);
//Test(0, V_MAX);
//Test(V_MIN, 0);
//Test(V_MIN, V_MAX);
//Test(0, V_MIN);
Test2();
$stop(2);
end
cordic_atan_iq dut(.*);
task Test(bit signed [29:0] I, Q);
int atan_ref, ang_delta, abs_ref, abs_res, abs_delta;
IS = I;
QS = Q;
repeat(100) @(posedge clk);
atan_ref = atan_iq_int(int'(IS), int'(QS));
ang_delta = delta(atan_ref, angle);
pct = rel_pct(atan_ref, angle);
$display("%d {%08h, %08h}: Ref %g deg (%d), RTL %g deg (%d), delta %d (%g pct)", i, int'(IS), int'(QS), int_to_deg(atan_ref), atan_ref, int_to_deg(angle), angle, ang_delta, pct);
abs_ref = imag(I, Q);
abs_res = int'(ConstPkg::K * real'(coe_radius));
abs_delta = delta(abs_ref, abs_res);
$display("\tAbs: x[end] = %08h, Ref %d, RTL %d, delta %d", coe_radius, abs_ref, abs_res, abs_delta);
assert (iabs(ang_delta) <= 16 && iabs(abs_delta) <= 16) else $display("ERROR!");
endtask
task Test2();
int atan_ref, ang_delta, abs_ref, abs_res, abs_delta;
int I, Q;
automatic bit error = 0;
// automatic IQArrayList v = GenIQ();
automatic IQArrayList v = GenIQ(1024);
fork
begin
for (int i = 0; i < v.size(); i++) begin
IS = v.data[i].I;
QS = v.data[i].Q;
@(posedge clk);
end
end
begin
repeat(32+1) @(posedge clk);
for (int i = 0; i < v.size(); i++) begin
I = v.data[i].I;
Q = v.data[i].Q;
atan_ref = atan_iq_int(I, Q);
ang_delta = delta(atan_ref, angle);
if (ang_delta > ang_delta_max) ang_delta_max = ang_delta;
if (ang_delta < ang_delta_min) ang_delta_min = ang_delta;
pct = rel_pct(atan_ref, angle);
$display("%d {%08h, %08h}. Angle: Ref %g deg (%d), RTL %g deg (%d), delta %d (%g pct)", i, I, Q, int_to_deg(atan_ref), atan_ref, int_to_deg(angle), angle, ang_delta, pct);
abs_ref = imag(I, Q);
abs_res = int'(ConstPkg::K * real'(coe_radius));
abs_delta = delta(abs_ref, abs_res);
if (abs_delta > abs_delta_max) abs_delta_max = abs_delta;
if (abs_delta < abs_delta_min) abs_delta_min = abs_delta;
$display("\tAbs: x[end] = %08h, Ref %d, RTL %d, delta %d", coe_radius, abs_ref, abs_res, abs_delta);
assert (iabs(ang_delta) <= 16 && iabs(abs_delta) <= 16)
else
begin
error = 1;
$display("ERROR!");
end
@(posedge clk);
end
if (error)
$display("Result: ERROR!");
else
$display("Result: OK");
end
join
$display("Calculation precision. Angle: [%d, %d] ([%g, %g] sec)", ang_delta_min, ang_delta_max, int_to_deg(ang_delta_min) * 60**2, int_to_deg(ang_delta_max) * 60**2);
$display("\tAbs: [%d, %d])", abs_delta_min, abs_delta_max);
repeat(100) @(posedge clk);
$stop(2);
endtask
//
wire [31:0][31:0] x;
wire [30:0][31:0] y;
wire [31:1][31:0] a;
genvar k;
generate for (k = 0; k < 32; k++)
begin :gen_x
assign x[k] = dut.x[k];
end
endgenerate
genvar n;
generate for (n = 0; n < 31; n++)
begin :gen_y
assign y[n] = dut.y[n];
end
endgenerate
genvar m;
generate for (m = 1; m < 32; m++)
begin :gen_a
assign a[m] = dut.a[m];
end
endgenerate
endmodule :cordic_atan_iq_tb
/cordic_atan_iq/cordic_atan_test.m
0,0 → 1,11
clc
 
I = 20e6;
Q = 4e6;
 
[angle, isqrt] = cordic_atan_iq(20e6, 4e6);
a = atan(Q/I) * 180 / pi;
iq_sqrt = int32(sqrt(I^2 + Q^2));
delta = iq_sqrt - isqrt;
 
fprintf('\nAngle MatLab: %g, Cordic: %g; SQRT MatLab: %d, Cordic: %d, delta %d\n', a, angle, iq_sqrt, isqrt, delta);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.