1 |
6 |
root |
/*
|
2 |
|
|
|
3 |
|
|
Copyright (c) 2003 Launchbird Design Systems, Inc.
|
4 |
|
|
|
5 |
|
|
C test bench for State Space Processor.
|
6 |
|
|
Demonstrates a vectoring cordic.
|
7 |
|
|
|
8 |
|
|
State Space Processor is configured for 16-bit data and
|
9 |
|
|
an 8-bit instruction memory address bus.
|
10 |
|
|
|
11 |
|
|
*/
|
12 |
|
|
|
13 |
|
|
#include <stdio.h>
|
14 |
|
|
#include "cf_ssp_16_8.h"
|
15 |
|
|
|
16 |
|
|
// State Space Processor Inputs
|
17 |
|
|
|
18 |
|
|
static unsigned char reset[1];
|
19 |
|
|
static unsigned char cycle[1];
|
20 |
|
|
static unsigned char instr_data[2];
|
21 |
|
|
static unsigned char const_data[2];
|
22 |
|
|
static unsigned char load_write[1];
|
23 |
|
|
static unsigned char load_addr[1];
|
24 |
|
|
static unsigned char load_data[2];
|
25 |
|
|
|
26 |
|
|
// State Space Processor Outputs
|
27 |
|
|
|
28 |
|
|
static unsigned char done[1];
|
29 |
|
|
static unsigned char instr_addr[1];
|
30 |
|
|
static unsigned char const_addr[1];
|
31 |
|
|
static unsigned char reg_0[2];
|
32 |
|
|
static unsigned char reg_1[2];
|
33 |
|
|
static unsigned char reg_2[2];
|
34 |
|
|
static unsigned char reg_3[2];
|
35 |
|
|
static unsigned char reg_4[2];
|
36 |
|
|
static unsigned char reg_5[2];
|
37 |
|
|
static unsigned char reg_6[2];
|
38 |
|
|
static unsigned char reg_7[2];
|
39 |
|
|
static unsigned char reg_8[2];
|
40 |
|
|
static unsigned char reg_9[2];
|
41 |
|
|
static unsigned char reg_a[2];
|
42 |
|
|
static unsigned char reg_b[2];
|
43 |
|
|
static unsigned char reg_c[2];
|
44 |
|
|
static unsigned char reg_d[2];
|
45 |
|
|
static unsigned char reg_e[2];
|
46 |
|
|
static unsigned char reg_f[2];
|
47 |
|
|
|
48 |
|
|
// External Constant Coefficient Memory
|
49 |
|
|
|
50 |
|
|
static unsigned int mem_const[256];
|
51 |
|
|
|
52 |
|
|
// External Instruction Memory
|
53 |
|
|
|
54 |
|
|
static unsigned int mem_instr[256];
|
55 |
|
|
|
56 |
|
|
// Constant Memory Initialization
|
57 |
|
|
|
58 |
|
|
void init_mem_const() {
|
59 |
|
|
|
60 |
|
|
// Cordic atan factors:
|
61 |
|
|
|
62 |
|
|
mem_const[0x00] = 0x2000; // Cordic atan factor for stage 0. 0010000000000000
|
63 |
|
|
mem_const[0x01] = 0x12E4; // Cordic atan factor for stage 1. 0001001011100100
|
64 |
|
|
mem_const[0x02] = 0x09FB; // Cordic atan factor for stage 2. 0000100111111011
|
65 |
|
|
mem_const[0x03] = 0x0511; // Cordic atan factor for stage 3. 0000010100010001
|
66 |
|
|
mem_const[0x04] = 0x028B; // Cordic atan factor for stage 4. 0000001010001011
|
67 |
|
|
mem_const[0x05] = 0x0146; // Cordic atan factor for stage 5. 0000000101000110
|
68 |
|
|
mem_const[0x06] = 0x00A3; // Cordic atan factor for stage 6. 0000000010100011
|
69 |
|
|
mem_const[0x07] = 0x00A1; // Cordic atan factor for stage 7. 0000000001010001
|
70 |
|
|
mem_const[0x08] = 0x0029; // Cordic atan factor for stage 8. 0000000000101001
|
71 |
|
|
mem_const[0x09] = 0x0014; // Cordic atan factor for stage 9. 0000000000010100
|
72 |
|
|
mem_const[0x0A] = 0x000A; // Cordic atan factor for stage A. 0000000000001010
|
73 |
|
|
mem_const[0x0B] = 0x0005; // Cordic atan factor for stage B. 0000000000000101
|
74 |
|
|
mem_const[0x0C] = 0x0003; // Cordic atan factor for stage C. 0000000000000011
|
75 |
|
|
mem_const[0x0D] = 0x0001; // Cordic atan factor for stage D. 0000000000000001
|
76 |
|
|
mem_const[0x0E] = 0x0001; // Cordic atan factor for stage E. 0000000000000001
|
77 |
|
|
mem_const[0x0F] = 0x0000; // Cordic atan factor for stage F. 0000000000000000
|
78 |
|
|
|
79 |
|
|
mem_const[0x10] = 0x8000; // 180 degrees.
|
80 |
|
|
|
81 |
|
|
}
|
82 |
|
|
|
83 |
|
|
// Instruction Memory Initialization
|
84 |
|
|
|
85 |
|
|
void init_mem_instr() {
|
86 |
|
|
int i = 0;
|
87 |
|
|
|
88 |
|
|
// Inputs
|
89 |
|
|
// r1: real (cordic x-axis input).
|
90 |
|
|
// r2: imag (cordic y-axis input).
|
91 |
|
|
|
92 |
|
|
// Cordic Register Usage:
|
93 |
|
|
// r1: Real input and rcc option.
|
94 |
|
|
// r2: Imag input and rcc option.
|
95 |
|
|
// r3: Angle input and rcc option.
|
96 |
|
|
// r4: Real rc option.
|
97 |
|
|
// r5: Imag rc option.
|
98 |
|
|
// r6: Angle rc option.
|
99 |
|
|
// r7: Shifted real.
|
100 |
|
|
// r8: Shifted imag.
|
101 |
|
|
// r9: Atan factor.
|
102 |
|
|
// rA: Temporary. Holds input imag for switch comparison.
|
103 |
|
|
|
104 |
|
|
// Cordic initial flip stage.
|
105 |
|
|
mem_instr[i++] = 0x5014; // Sub r0, r1, r4 -- r4 holds 0 - real.
|
106 |
|
|
mem_instr[i++] = 0x5025; // Sub r0, r2, r5 -- r5 holds 0 - imag.
|
107 |
|
|
mem_instr[i++] = 0x0003; // ShiftLeft r0, r3 -- Load 0 in angle.
|
108 |
|
|
mem_instr[i++] = 0x7106; // Constant #10, r6 -- Load 180 degrees.
|
109 |
|
|
|
110 |
|
|
mem_instr[i++] = 0x5100; // Sub r1, r0, r9 -- Check if real < 0.
|
111 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
112 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
113 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
114 |
|
|
|
115 |
|
|
// Cordic stage 0.
|
116 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
117 |
|
|
mem_instr[i++] = 0x3017; // Add r0, r1, r7 -- Move r1 to r7. Stage 0 does not shift data.
|
118 |
|
|
mem_instr[i++] = 0x3028; // Add r0, r2, r8 -- Move r2 to r8.
|
119 |
|
|
mem_instr[i++] = 0x7009; // Constant #00, r9 -- Load atan factor 0.
|
120 |
|
|
|
121 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
122 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
123 |
|
|
|
124 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
125 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
126 |
|
|
|
127 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
128 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
129 |
|
|
|
130 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
131 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
132 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
133 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
134 |
|
|
|
135 |
|
|
// Cordic stage 1.
|
136 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
137 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 1
|
138 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 1
|
139 |
|
|
mem_instr[i++] = 0x7019; // Constant #01, r9 -- Load atan factor 1.
|
140 |
|
|
|
141 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
142 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
143 |
|
|
|
144 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
145 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
146 |
|
|
|
147 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
148 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
149 |
|
|
|
150 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
151 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
152 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
153 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
154 |
|
|
|
155 |
|
|
// Cordic stage 2.
|
156 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
157 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 2
|
158 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
159 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 2
|
160 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
161 |
|
|
mem_instr[i++] = 0x7029; // Constant #02, r9 -- Load atan factor 2.
|
162 |
|
|
|
163 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
164 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
165 |
|
|
|
166 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
167 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
168 |
|
|
|
169 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
170 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
171 |
|
|
|
172 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
173 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
174 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
175 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
176 |
|
|
|
177 |
|
|
// Cordic stage 3.
|
178 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
179 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 3
|
180 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
181 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
182 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 3
|
183 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
184 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
185 |
|
|
mem_instr[i++] = 0x7039; // Constant #03, r9 -- Load atan factor 3.
|
186 |
|
|
|
187 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
188 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
189 |
|
|
|
190 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
191 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
192 |
|
|
|
193 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
194 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
195 |
|
|
|
196 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
197 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
198 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
199 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
200 |
|
|
|
201 |
|
|
// Cordic stage 4.
|
202 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
203 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 4
|
204 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
205 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
206 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
207 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 4
|
208 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
209 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
210 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
211 |
|
|
mem_instr[i++] = 0x7049; // Constant #04, r9 -- Load atan factor 4.
|
212 |
|
|
|
213 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
214 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
215 |
|
|
|
216 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
217 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
218 |
|
|
|
219 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
220 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
221 |
|
|
|
222 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
223 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
224 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
225 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
226 |
|
|
|
227 |
|
|
// Cordic stage 5.
|
228 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
229 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 5
|
230 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
231 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
232 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
233 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
234 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 5
|
235 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
236 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
237 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
238 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
239 |
|
|
mem_instr[i++] = 0x7059; // Constant #05, r9 -- Load atan factor 5.
|
240 |
|
|
|
241 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
242 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
243 |
|
|
|
244 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
245 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
246 |
|
|
|
247 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
248 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
249 |
|
|
|
250 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
251 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
252 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
253 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
254 |
|
|
|
255 |
|
|
// Cordic stage 6.
|
256 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
257 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 6
|
258 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
259 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
260 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
261 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
262 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
263 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 6
|
264 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
265 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
266 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
267 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
268 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
269 |
|
|
mem_instr[i++] = 0x7069; // Constant #06, r9 -- Load atan factor 6.
|
270 |
|
|
|
271 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
272 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
273 |
|
|
|
274 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
275 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
276 |
|
|
|
277 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
278 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
279 |
|
|
|
280 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
281 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
282 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
283 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
284 |
|
|
|
285 |
|
|
// Cordic stage 7.
|
286 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
287 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 7
|
288 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
289 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
290 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
291 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
292 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
293 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
294 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 7
|
295 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
296 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
297 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
298 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
299 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
300 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
301 |
|
|
mem_instr[i++] = 0x7079; // Constant #07, r9 -- Load atan factor 7.
|
302 |
|
|
|
303 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
304 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
305 |
|
|
|
306 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
307 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
308 |
|
|
|
309 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
310 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
311 |
|
|
|
312 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
313 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
314 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
315 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
316 |
|
|
|
317 |
|
|
// Cordic stage 8.
|
318 |
|
|
mem_instr[i++] = 0x302A; // Add r0, r2, rA -- Save input imag.
|
319 |
|
|
mem_instr[i++] = 0x1107; // ShiftRight r1, r7 -- ShiftedReal = RealIn >> 8
|
320 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
321 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
322 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
323 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
324 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
325 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
326 |
|
|
mem_instr[i++] = 0x1707; // ShiftRight r7, r7
|
327 |
|
|
mem_instr[i++] = 0x1208; // ShiftRight r2, r8 -- ShiftedImag = ImagIn >> 8
|
328 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
329 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
330 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
331 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
332 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
333 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
334 |
|
|
mem_instr[i++] = 0x1808; // ShiftRight r8, r8
|
335 |
|
|
mem_instr[i++] = 0x7089; // Constant #08, r9 -- Load atan factor 8.
|
336 |
|
|
|
337 |
|
|
mem_instr[i++] = 0x3184; // Add r1, r8, r4 -- Real options (RealIn +/- ShiftedImag).
|
338 |
|
|
mem_instr[i++] = 0x5181; // Sub r1, r8, r1
|
339 |
|
|
|
340 |
|
|
mem_instr[i++] = 0x5275; // Sub r2, r7, r5 -- Imag options (ImagIn -/+ ShiftedReal).
|
341 |
|
|
mem_instr[i++] = 0x3272; // Add r2, r7, r2
|
342 |
|
|
|
343 |
|
|
mem_instr[i++] = 0x3396; // Add r3, r9, r6 -- Angle options (AngIn +/- AtanFactor).
|
344 |
|
|
mem_instr[i++] = 0x5393; // Sub r3, r9, r3
|
345 |
|
|
|
346 |
|
|
mem_instr[i++] = 0x50A0; // Sub r0, rA, r0 -- Check if imag > 0.
|
347 |
|
|
mem_instr[i++] = 0x6411; // Switch r4, r1, r1 -- Select real output.
|
348 |
|
|
mem_instr[i++] = 0x6522; // Switch r5, r2, r2 -- Select imag output.
|
349 |
|
|
mem_instr[i++] = 0x6633; // Switch r6, r3, r3 -- Select angle output.
|
350 |
|
|
|
351 |
|
|
// Halt processor cycle.
|
352 |
|
|
mem_instr[i++] = 0x8000; // Halt
|
353 |
|
|
|
354 |
|
|
printf("Number of Instructions: %d\n", i);
|
355 |
|
|
|
356 |
|
|
}
|
357 |
|
|
|
358 |
|
|
// Initialize simulation.
|
359 |
|
|
|
360 |
|
|
void sim_init() {
|
361 |
|
|
// Init memories.
|
362 |
|
|
init_mem_const();
|
363 |
|
|
init_mem_instr();
|
364 |
|
|
|
365 |
|
|
// Clear input data.
|
366 |
|
|
reset[0] = 0;
|
367 |
|
|
cycle[0] = 0;
|
368 |
|
|
instr_data[1] = 0; instr_data[0] = 0;
|
369 |
|
|
const_data[1] = 0; const_data[0] = 0;
|
370 |
|
|
load_write[0] = 0;
|
371 |
|
|
load_addr[0] = 0;
|
372 |
|
|
load_data[1] = 0; load_data[0] = 0;
|
373 |
|
|
|
374 |
|
|
// Bind ports.
|
375 |
|
|
cf_ssp_16_8_ports(reset, cycle, instr_data, const_data, load_write, load_addr, load_data,
|
376 |
|
|
done, instr_addr, const_addr,
|
377 |
|
|
reg_0, reg_1, reg_2, reg_3, reg_4, reg_5, reg_6, reg_7,
|
378 |
|
|
reg_8, reg_9, reg_a, reg_b, reg_c, reg_d, reg_e, reg_f);
|
379 |
|
|
|
380 |
|
|
// Init model and VCD recording.
|
381 |
|
|
cf_ssp_16_8_sim_init("cf_ssp_cordic.vcd");
|
382 |
|
|
}
|
383 |
|
|
|
384 |
|
|
// End simulation.
|
385 |
|
|
|
386 |
|
|
void sim_end() {
|
387 |
|
|
// End VCD recording.
|
388 |
|
|
cf_ssp_16_8_sim_end();
|
389 |
|
|
}
|
390 |
|
|
|
391 |
|
|
// Cycle simulation.
|
392 |
|
|
|
393 |
|
|
void sim_cycle() {
|
394 |
|
|
cf_ssp_16_8_calc();
|
395 |
|
|
cf_ssp_16_8_sim_sample();
|
396 |
|
|
cf_ssp_16_8_cycle_clock();
|
397 |
|
|
// Fetch instruction from instruction memory.
|
398 |
|
|
instr_data[0] = (unsigned char) (mem_instr[instr_addr[0]] & 0xFF);
|
399 |
|
|
instr_data[1] = (unsigned char) (mem_instr[instr_addr[0]] >> 8 & 0xFF);
|
400 |
|
|
// Fetch constant from constant memory.
|
401 |
|
|
const_data[0] = (unsigned char) (mem_const[const_addr[0]] & 0xFF);
|
402 |
|
|
const_data[1] = (unsigned char) (mem_const[const_addr[0]] >> 8 & 0xFF);
|
403 |
|
|
}
|
404 |
|
|
|
405 |
|
|
// Reset Processor
|
406 |
|
|
|
407 |
|
|
void processor_reset() {
|
408 |
|
|
reset[0] = 1;
|
409 |
|
|
sim_cycle();
|
410 |
|
|
reset[0] = 0;
|
411 |
|
|
}
|
412 |
|
|
|
413 |
|
|
// Cycle Processor
|
414 |
|
|
|
415 |
|
|
void processor_cycle(int real, int imag) {
|
416 |
|
|
int real_out, imag_out, angle_out;
|
417 |
|
|
|
418 |
|
|
// Load real input into register 1.
|
419 |
|
|
load_write[0] = 1;
|
420 |
|
|
load_addr[0] = 1;
|
421 |
|
|
load_data[0] = (unsigned char) (real & 0xFF);
|
422 |
|
|
load_data[1] = (unsigned char) (real >> 8 & 0xFF);
|
423 |
|
|
sim_cycle();
|
424 |
|
|
|
425 |
|
|
// Load imag input into register 2.
|
426 |
|
|
load_write[0] = 1;
|
427 |
|
|
load_addr[0] = 2;
|
428 |
|
|
load_data[0] = (unsigned char) (imag & 0xFF);
|
429 |
|
|
load_data[1] = (unsigned char) (imag >> 8 & 0xFF);
|
430 |
|
|
sim_cycle();
|
431 |
|
|
|
432 |
|
|
// Signal processor to start cycle.
|
433 |
|
|
load_write[0] = 0;
|
434 |
|
|
cycle[0] = 1;
|
435 |
|
|
sim_cycle();
|
436 |
|
|
cycle[0] = 0;
|
437 |
|
|
sim_cycle();
|
438 |
|
|
|
439 |
|
|
// Cycle processor until done.
|
440 |
|
|
while (!done[0]) sim_cycle();
|
441 |
|
|
|
442 |
|
|
// Extract real, imag, and angle results from registers.
|
443 |
|
|
real_out = (int) reg_1[1] << 8 | (int) reg_1[0];
|
444 |
|
|
imag_out = (int) reg_2[1] << 8 | (int) reg_2[0];
|
445 |
|
|
angle_out = (int) reg_3[1] << 8 | (int) reg_3[0];
|
446 |
|
|
|
447 |
|
|
printf("RealIn: 0x%04X ImagIn: 0x%04X RealOut: 0x%04X ImagOut: 0x%04X AngleOut: 0x%04X\n", real, imag, real_out, imag_out, angle_out);
|
448 |
|
|
}
|
449 |
|
|
|
450 |
|
|
|
451 |
|
|
int main(int argc, char *argv[]) {
|
452 |
|
|
sim_init();
|
453 |
|
|
processor_reset();
|
454 |
|
|
processor_cycle(0x0100, 0x0000);
|
455 |
|
|
processor_cycle(0x0100, 0x0100);
|
456 |
|
|
processor_cycle(0x0000, 0x0100);
|
457 |
|
|
processor_cycle(0xFF00, 0x0100);
|
458 |
|
|
processor_cycle(0xFF00, 0x0000);
|
459 |
|
|
processor_cycle(0xFF00, 0xFF00);
|
460 |
|
|
processor_cycle(0x0000, 0xFF00);
|
461 |
|
|
processor_cycle(0x0100, 0x0000);
|
462 |
|
|
sim_end();
|
463 |
|
|
return 0;
|
464 |
|
|
}
|
465 |
|
|
|