1 |
2 |
daledrinka |
`timescale 1ns/1ns
|
2 |
|
|
/*
|
3 |
|
|
CORDIC testbench
|
4 |
|
|
|
5 |
|
|
This testbench assumes the default settings for `defines
|
6 |
|
|
in the cordic.v file. If you change any of the defaults
|
7 |
|
|
you may have to make modifications to this file as well.
|
8 |
|
|
|
9 |
|
|
This testbench uses `defines from the cordic.v file
|
10 |
|
|
make sure you have the `include path set correctly for your
|
11 |
|
|
environment.
|
12 |
|
|
*/
|
13 |
|
|
`include "cordic.v"
|
14 |
|
|
module tb ();
|
15 |
|
|
|
16 |
|
|
wire [`XY_BITS:0] x_o,y_o;
|
17 |
|
|
wire [`THETA_BITS:0] theta_o;
|
18 |
|
|
reg [`XY_BITS:0] x_i,y_i;
|
19 |
|
|
reg [`THETA_BITS:0] theta_i; // angle in radians
|
20 |
|
|
reg clock,reset;
|
21 |
|
|
reg init;
|
22 |
|
|
|
23 |
|
|
cordic UUT (.clk(clock),.rst(reset),
|
24 |
|
|
`ifdef ITERATE
|
25 |
|
|
.init(init),
|
26 |
|
|
`endif
|
27 |
|
|
.x_i(x_i),.y_i(y_i),.theta_i(theta_i),
|
28 |
|
|
.x_o(x_o),.y_o(y_o),.theta_o(theta_o));
|
29 |
|
|
|
30 |
|
|
integer i,j,k;
|
31 |
|
|
real a_i,a_o,a_e;
|
32 |
|
|
real rx,ry,rex,rey;
|
33 |
|
|
|
34 |
|
|
reg signed [`XY_BITS:0] ex,ey;
|
35 |
|
|
|
36 |
|
|
reg signed [16:0] x [90:0];
|
37 |
|
|
reg signed [16:0] y [90:0];
|
38 |
|
|
reg signed [16:0] z [90:0];
|
39 |
|
|
|
40 |
|
|
task show_vector_results;
|
41 |
|
|
input integer j;
|
42 |
|
|
input [`THETA_BITS:0] theta;
|
43 |
|
|
begin
|
44 |
|
|
a_i = (j * 3.14) / 180;
|
45 |
|
|
a_o = theta;
|
46 |
|
|
a_o = a_o / 32768;
|
47 |
|
|
if (a_o > a_i) a_e = a_o - a_i; else a_e = a_i - a_o;
|
48 |
|
|
if (a_e > 0.001)
|
49 |
|
|
$display("angle %f computed %f error %f",a_i,a_o,a_o - a_i);
|
50 |
|
|
else
|
51 |
|
|
$display("angle %f computed %f",a_i,a_o);
|
52 |
|
|
end
|
53 |
|
|
endtask
|
54 |
|
|
|
55 |
|
|
task show_rotate_results;
|
56 |
|
|
input integer j;
|
57 |
|
|
input [`XY_BITS:0] lx;
|
58 |
|
|
input [`XY_BITS:0] ly;
|
59 |
|
|
begin
|
60 |
|
|
rx = lx;// / 65535;
|
61 |
|
|
ry = ly;// / 65535;
|
62 |
|
|
rx = rx / 32768; //65535;
|
63 |
|
|
ry = ry / 32768; //65535;
|
64 |
|
|
if (lx > x[j]) ex = lx - x[j]; else ex = x[j] - lx;
|
65 |
|
|
if (ly > y[j]) ey = ly - y[j]; else ey = y[j] - ly;
|
66 |
|
|
if (ex > 10 || ey > 10)
|
67 |
|
|
$display("Angle: %d sin = %f cos = %f errors %d %d",j,ry,rx,ey,ex);
|
68 |
|
|
else
|
69 |
|
|
$display("Angle: %d sin = %f cos = %f",j,ry,rx);
|
70 |
|
|
end
|
71 |
|
|
endtask
|
72 |
|
|
|
73 |
|
|
task show_results;
|
74 |
|
|
input integer j;
|
75 |
|
|
input [`XY_BITS:0] lx;
|
76 |
|
|
input [`XY_BITS:0] ly;
|
77 |
|
|
input [`THETA_BITS:0] ltheta;
|
78 |
|
|
begin
|
79 |
|
|
`ifdef VECTOR
|
80 |
|
|
show_vector_results(j,ltheta);
|
81 |
|
|
`endif
|
82 |
|
|
`ifdef ROTATE
|
83 |
|
|
show_rotate_results(j,lx,ly);
|
84 |
|
|
`endif
|
85 |
|
|
end
|
86 |
|
|
endtask
|
87 |
|
|
initial begin
|
88 |
|
|
$display("starting simulation");
|
89 |
|
|
`ifdef PIPELINE
|
90 |
|
|
$display("PIPELINE configuration");
|
91 |
|
|
`endif
|
92 |
|
|
`ifdef ITERATE
|
93 |
|
|
$display("ITERATE configuration");
|
94 |
|
|
`endif
|
95 |
|
|
`ifdef COMBINATORIAL
|
96 |
|
|
$display("COMBINATORIAL configuration");
|
97 |
|
|
`endif
|
98 |
|
|
|
99 |
|
|
// The following table is computed for U(1,15) format numbers
|
100 |
|
|
// The angle data z[] is in radians
|
101 |
|
|
x[0] <= 17'd32768; y[0] <= 17'd0; z[0] <= 17'd0;
|
102 |
|
|
x[1] <= 17'd32763; y[1] <= 17'd571; z[1] <= 17'd571;
|
103 |
|
|
x[2] <= 17'd32748; y[2] <= 17'd1143; z[2] <= 17'd1143;
|
104 |
|
|
x[3] <= 17'd32723; y[3] <= 17'd1714; z[3] <= 17'd1715;
|
105 |
|
|
x[4] <= 17'd32688; y[4] <= 17'd2285; z[4] <= 17'd2287;
|
106 |
|
|
x[5] <= 17'd32643; y[5] <= 17'd2855; z[5] <= 17'd2859;
|
107 |
|
|
x[6] <= 17'd32588; y[6] <= 17'd3425; z[6] <= 17'd3431;
|
108 |
|
|
x[7] <= 17'd32523; y[7] <= 17'd3993; z[7] <= 17'd4003;
|
109 |
|
|
x[8] <= 17'd32449; y[8] <= 17'd4560; z[8] <= 17'd4575;
|
110 |
|
|
x[9] <= 17'd32364; y[9] <= 17'd5126; z[9] <= 17'd5147;
|
111 |
|
|
x[10] <= 17'd32270; y[10] <= 17'd5690; z[10] <= 17'd5719;
|
112 |
|
|
x[11] <= 17'd32165; y[11] <= 17'd6252; z[11] <= 17'd6291;
|
113 |
|
|
x[12] <= 17'd32051; y[12] <= 17'd6812; z[12] <= 17'd6862;
|
114 |
|
|
x[13] <= 17'd31928; y[13] <= 17'd7371; z[13] <= 17'd7434;
|
115 |
|
|
x[14] <= 17'd31794; y[14] <= 17'd7927; z[14] <= 17'd8006;
|
116 |
|
|
x[15] <= 17'd31651; y[15] <= 17'd8480; z[15] <= 17'd8578;
|
117 |
|
|
x[16] <= 17'd31498; y[16] <= 17'd9032; z[16] <= 17'd9150;
|
118 |
|
|
x[17] <= 17'd31336; y[17] <= 17'd9580; z[17] <= 17'd9722;
|
119 |
|
|
x[18] <= 17'd31164; y[18] <= 17'd10125; z[18] <= 17'd10294;
|
120 |
|
|
x[19] <= 17'd30982; y[19] <= 17'd10668; z[19] <= 17'd10866;
|
121 |
|
|
x[20] <= 17'd30791; y[20] <= 17'd11207; z[20] <= 17'd11438;
|
122 |
|
|
x[21] <= 17'd30591; y[21] <= 17'd11743; z[21] <= 17'd12010;
|
123 |
|
|
x[22] <= 17'd30381; y[22] <= 17'd12275; z[22] <= 17'd12582;
|
124 |
|
|
x[23] <= 17'd30163; y[23] <= 17'd12803; z[23] <= 17'd13153;
|
125 |
|
|
x[24] <= 17'd29935; y[24] <= 17'd13327; z[24] <= 17'd13725;
|
126 |
|
|
x[25] <= 17'd29697; y[25] <= 17'd13848; z[25] <= 17'd14297;
|
127 |
|
|
x[26] <= 17'd29451; y[26] <= 17'd14364; z[26] <= 17'd14869;
|
128 |
|
|
x[27] <= 17'd29196; y[27] <= 17'd14876; z[27] <= 17'd15441;
|
129 |
|
|
x[28] <= 17'd28932; y[28] <= 17'd15383; z[28] <= 17'd16013;
|
130 |
|
|
x[29] <= 17'd28659; y[29] <= 17'd15886; z[29] <= 17'd16585;
|
131 |
|
|
x[30] <= 17'd28377; y[30] <= 17'd16383; z[30] <= 17'd17157;
|
132 |
|
|
x[31] <= 17'd28087; y[31] <= 17'd16876; z[31] <= 17'd17729;
|
133 |
|
|
x[32] <= 17'd27788; y[32] <= 17'd17364; z[32] <= 17'd18301;
|
134 |
|
|
x[33] <= 17'd27481; y[33] <= 17'd17846; z[33] <= 17'd18873;
|
135 |
|
|
x[34] <= 17'd27165; y[34] <= 17'd18323; z[34] <= 17'd19444;
|
136 |
|
|
x[35] <= 17'd26841; y[35] <= 17'd18794; z[35] <= 17'd20016;
|
137 |
|
|
x[36] <= 17'd26509; y[36] <= 17'd19260; z[36] <= 17'd20588;
|
138 |
|
|
x[37] <= 17'd26169; y[37] <= 17'd19720; z[37] <= 17'd21160;
|
139 |
|
|
x[38] <= 17'd25821; y[38] <= 17'd20173; z[38] <= 17'd21732;
|
140 |
|
|
x[39] <= 17'd25465; y[39] <= 17'd20621; z[39] <= 17'd22304;
|
141 |
|
|
x[40] <= 17'd25101; y[40] <= 17'd21062; z[40] <= 17'd22876;
|
142 |
|
|
x[41] <= 17'd24730; y[41] <= 17'd21497; z[41] <= 17'd23448;
|
143 |
|
|
x[42] <= 17'd24351; y[42] <= 17'd21926; z[42] <= 17'd24020;
|
144 |
|
|
x[43] <= 17'd23964; y[43] <= 17'd22347; z[43] <= 17'd24592;
|
145 |
|
|
x[44] <= 17'd23571; y[44] <= 17'd22762; z[44] <= 17'd25164;
|
146 |
|
|
x[45] <= 17'd23170; y[45] <= 17'd23170; z[45] <= 17'd25735;
|
147 |
|
|
x[46] <= 17'd22762; y[46] <= 17'd23571; z[46] <= 17'd26307;
|
148 |
|
|
x[47] <= 17'd22347; y[47] <= 17'd23964; z[47] <= 17'd26879;
|
149 |
|
|
x[48] <= 17'd21926; y[48] <= 17'd24351; z[48] <= 17'd27451;
|
150 |
|
|
x[49] <= 17'd21497; y[49] <= 17'd24730; z[49] <= 17'd28023;
|
151 |
|
|
x[50] <= 17'd21062; y[50] <= 17'd25101; z[50] <= 17'd28595;
|
152 |
|
|
x[51] <= 17'd20621; y[51] <= 17'd25465; z[51] <= 17'd29167;
|
153 |
|
|
x[52] <= 17'd20173; y[52] <= 17'd25821; z[52] <= 17'd29739;
|
154 |
|
|
x[53] <= 17'd19720; y[53] <= 17'd26169; z[53] <= 17'd30311;
|
155 |
|
|
x[54] <= 17'd19260; y[54] <= 17'd26509; z[54] <= 17'd30883;
|
156 |
|
|
x[55] <= 17'd18794; y[55] <= 17'd26841; z[55] <= 17'd31455;
|
157 |
|
|
x[56] <= 17'd18323; y[56] <= 17'd27165; z[56] <= 17'd32026;
|
158 |
|
|
x[57] <= 17'd17846; y[57] <= 17'd27481; z[57] <= 17'd32598;
|
159 |
|
|
x[58] <= 17'd17364; y[58] <= 17'd27788; z[58] <= 17'd33170;
|
160 |
|
|
x[59] <= 17'd16876; y[59] <= 17'd28087; z[59] <= 17'd33742;
|
161 |
|
|
x[60] <= 17'd16384; y[60] <= 17'd28377; z[60] <= 17'd34314;
|
162 |
|
|
x[61] <= 17'd15886; y[61] <= 17'd28659; z[61] <= 17'd34886;
|
163 |
|
|
x[62] <= 17'd15383; y[62] <= 17'd28932; z[62] <= 17'd35458;
|
164 |
|
|
x[63] <= 17'd14876; y[63] <= 17'd29196; z[63] <= 17'd36030;
|
165 |
|
|
x[64] <= 17'd14364; y[64] <= 17'd29451; z[64] <= 17'd36602;
|
166 |
|
|
x[65] <= 17'd13848; y[65] <= 17'd29697; z[65] <= 17'd37174;
|
167 |
|
|
x[66] <= 17'd13327; y[66] <= 17'd29935; z[66] <= 17'd37746;
|
168 |
|
|
x[67] <= 17'd12803; y[67] <= 17'd30163; z[67] <= 17'd38317;
|
169 |
|
|
x[68] <= 17'd12275; y[68] <= 17'd30381; z[68] <= 17'd38889;
|
170 |
|
|
x[69] <= 17'd11743; y[69] <= 17'd30591; z[69] <= 17'd39461;
|
171 |
|
|
x[70] <= 17'd11207; y[70] <= 17'd30791; z[70] <= 17'd40033;
|
172 |
|
|
x[71] <= 17'd10668; y[71] <= 17'd30982; z[71] <= 17'd40605;
|
173 |
|
|
x[72] <= 17'd10125; y[72] <= 17'd31164; z[72] <= 17'd41177;
|
174 |
|
|
x[73] <= 17'd9580; y[73] <= 17'd31336; z[73] <= 17'd41749;
|
175 |
|
|
x[74] <= 17'd9032; y[74] <= 17'd31498; z[74] <= 17'd42321;
|
176 |
|
|
x[75] <= 17'd8480; y[75] <= 17'd31651; z[75] <= 17'd42893;
|
177 |
|
|
x[76] <= 17'd7927; y[76] <= 17'd31794; z[76] <= 17'd43465;
|
178 |
|
|
x[77] <= 17'd7371; y[77] <= 17'd31928; z[77] <= 17'd44037;
|
179 |
|
|
x[78] <= 17'd6812; y[78] <= 17'd32051; z[78] <= 17'd44608;
|
180 |
|
|
x[79] <= 17'd6252; y[79] <= 17'd32165; z[79] <= 17'd45180;
|
181 |
|
|
x[80] <= 17'd5690; y[80] <= 17'd32270; z[80] <= 17'd45752;
|
182 |
|
|
x[81] <= 17'd5126; y[81] <= 17'd32364; z[81] <= 17'd46324;
|
183 |
|
|
x[82] <= 17'd4560; y[82] <= 17'd32449; z[82] <= 17'd46896;
|
184 |
|
|
x[83] <= 17'd3993; y[83] <= 17'd32523; z[83] <= 17'd47468;
|
185 |
|
|
x[84] <= 17'd3425; y[84] <= 17'd32588; z[84] <= 17'd48040;
|
186 |
|
|
x[85] <= 17'd2855; y[85] <= 17'd32643; z[85] <= 17'd48612;
|
187 |
|
|
x[86] <= 17'd2285; y[86] <= 17'd32688; z[86] <= 17'd49184;
|
188 |
|
|
x[87] <= 17'd1714; y[87] <= 17'd32723; z[87] <= 17'd49756;
|
189 |
|
|
x[88] <= 17'd1143; y[88] <= 17'd32748; z[88] <= 17'd50328;
|
190 |
|
|
x[89] <= 17'd571; y[89] <= 17'd32763; z[89] <= 17'd50899;
|
191 |
|
|
x[90] <= 17'd0; y[90] <= 17'd32768; z[90] <= 17'd51471;
|
192 |
|
|
|
193 |
|
|
clock <= 0;
|
194 |
|
|
init <= 0;
|
195 |
|
|
reset <= 1;
|
196 |
|
|
x_i <= 0;
|
197 |
|
|
y_i <= 0;
|
198 |
|
|
theta_i <= 0;
|
199 |
|
|
#1 clock <= 1;
|
200 |
|
|
#1 clock <= 0;
|
201 |
|
|
reset <= 0;
|
202 |
|
|
|
203 |
|
|
for (j=0;j<=90;j = j+1) begin // test 91 different angles, 0 to 90 degrees
|
204 |
|
|
`ifdef ROTATE // compute sin and cos
|
205 |
|
|
x_i <= `CORDIC_1;
|
206 |
|
|
y_i <= 0;
|
207 |
|
|
theta_i <= z[j];
|
208 |
|
|
`endif
|
209 |
|
|
`ifdef VECTOR // compute the arctan
|
210 |
|
|
x_i <= x[j];
|
211 |
|
|
y_i <= y[j];
|
212 |
|
|
theta_i <= 0;
|
213 |
|
|
`endif
|
214 |
|
|
|
215 |
|
|
|
216 |
|
|
`ifdef ITERATE
|
217 |
|
|
init <= 1; // load the value into the rotator
|
218 |
|
|
#1 clock <= 1;
|
219 |
|
|
#1 clock <= 0;
|
220 |
|
|
init <= 0;
|
221 |
|
|
for(i=0;i<`ITERATIONS;i = i+1) begin // iterate on the value
|
222 |
|
|
#1 clock <= 1;
|
223 |
|
|
#1 clock <= 0;
|
224 |
|
|
end
|
225 |
|
|
show_results(j,x_o,y_o,theta_o);
|
226 |
|
|
`endif
|
227 |
|
|
|
228 |
|
|
|
229 |
|
|
`ifdef COMBINATORIAL
|
230 |
|
|
#1; // give a little time to view the waveform...
|
231 |
|
|
show_results(j,x_o,y_o,theta_o);
|
232 |
|
|
`endif
|
233 |
|
|
|
234 |
|
|
`ifdef PIPELINE
|
235 |
|
|
#1 clock <= 1;
|
236 |
|
|
#1 clock <= 0;
|
237 |
|
|
if (j >= (`ITERATIONS-2)) begin // wait until the results start popping out
|
238 |
|
|
show_results((j-(`ITERATIONS-2)),x_o,y_o,theta_o);
|
239 |
|
|
end
|
240 |
|
|
if (j == 90) // now flush the pipe
|
241 |
|
|
for(i=0;i<(`ITERATIONS-2);i = i+1) begin
|
242 |
|
|
#1 clock <= 1;
|
243 |
|
|
#1 clock <= 0;
|
244 |
|
|
show_results((90-`ITERATIONS+3+i),x_o,y_o,theta_o);
|
245 |
|
|
end
|
246 |
|
|
`endif
|
247 |
|
|
|
248 |
|
|
|
249 |
|
|
end
|
250 |
|
|
for(i=0;i<16;i=i+1) // dump a few extra clock just for grins
|
251 |
|
|
#1 clock <= ~clock;
|
252 |
|
|
end
|
253 |
|
|
|
254 |
|
|
endmodule
|