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

Subversion Repositories aemb

[/] [aemb/] [tags/] [AEMB_711/] [sw/] [c/] [aeMB_testbench.c] - Blame information for rev 206

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sybreon
/*
2 67 sybreon
 * $Id: aeMB_testbench.c,v 1.12 2007-11-18 19:41:45 sybreon Exp $
3 2 sybreon
 *
4 6 sybreon
 * AEMB Function Verification C Testbench
5 29 sybreon
 * Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
6 2 sybreon
 *
7 29 sybreon
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11 2 sybreon
 *
12 29 sybreon
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
 * Lesser General Public License for more details.
16 2 sybreon
 *
17 29 sybreon
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20
 * USA
21 2 sybreon
 *
22 29 sybreon
 * DESCRIPTION
23
 * It tests a whole gamut of operations and is tightly linked to the
24
 * ae68_testbench.v testbench module for verification.
25 2 sybreon
 *
26
 * HISTORY
27
 * $Log: not supported by cvs2svn $
28 67 sybreon
 * Revision 1.11  2007/11/14 23:41:06  sybreon
29
 * Fixed minor interrupt test typo.
30
 *
31 64 sybreon
 * Revision 1.10  2007/11/14 22:12:02  sybreon
32
 * Added interrupt test routine.
33
 *
34 60 sybreon
 * Revision 1.9  2007/11/09 20:51:53  sybreon
35
 * Added GET/PUT support through a FSL bus.
36
 *
37 53 sybreon
 * Revision 1.8  2007/11/03 08:40:18  sybreon
38
 * Minor code cleanup.
39
 *
40 46 sybreon
 * Revision 1.7  2007/11/02 18:32:19  sybreon
41
 * Enable MSR_IE with software.
42
 *
43 42 sybreon
 * Revision 1.6  2007/04/30 15:57:10  sybreon
44
 * Removed byte acrobatics.
45
 *
46 31 sybreon
 * Revision 1.5  2007/04/27 15:17:59  sybreon
47
 * Added code documentation.
48
 * Added new tests that test floating point, modulo arithmetic and multiplication/division.
49
 *
50 29 sybreon
 * Revision 1.4  2007/04/25 22:15:05  sybreon
51
 * Added support for 8-bit and 16-bit data types.
52
 *
53 22 sybreon
 * Revision 1.3  2007/04/04 14:09:04  sybreon
54
 * Added initial interrupt/exception support.
55
 *
56 14 sybreon
 * Revision 1.2  2007/04/04 06:07:45  sybreon
57
 * Fixed C code bug which passes the test
58
 *
59 6 sybreon
 * Revision 1.1  2007/03/09 17:41:57  sybreon
60
 * initial import
61
 *
62 2 sybreon
 */
63
 
64 29 sybreon
/**
65
   INTERRUPT TEST
66
 
67
   This tests for the following:
68
   - Pointer addressing
69
   - Interrupt handling
70
 */
71 67 sybreon
 
72 46 sybreon
void int_handler (void) __attribute__ ((interrupt_handler));
73 67 sybreon
volatile int service = 0xDEADDEAD;
74
 
75 46 sybreon
void int_enable()
76
{
77 60 sybreon
  int tmp;
78 67 sybreon
  asm volatile ("mfs %0, rmsr;"
79
                "ori %1, %0, 0x02;"
80
                "mts rmsr, %1;"
81
                : "=r" (tmp)
82
                : "r" (tmp));
83 46 sybreon
}
84 42 sybreon
 
85 46 sybreon
void int_disable()
86
{
87 60 sybreon
  int tmp;
88 67 sybreon
  asm volatile ("mfs %0, rmsr;"
89
                "andi %1, %0, 0xFD;"
90
                "mts rmsr, %1;"
91
                : "=r" (tmp)
92
                : "r" (tmp));
93 6 sybreon
}
94 2 sybreon
 
95 46 sybreon
void int_service()
96
{
97
  int* pio = (int*)0xFFFFFFFC;
98 29 sybreon
  *pio = 0x52544E49; // "INTR"
99 67 sybreon
  service = 0;
100 6 sybreon
}
101 2 sybreon
 
102 46 sybreon
void int_handler()
103
{
104
  int_service();
105
}
106
 
107 60 sybreon
/**
108
   INTERRUPT TEST ROUTINE
109
*/
110
int int_test ()
111
{
112
  // Delay loop until hardware interrupt triggers
113 67 sybreon
  for (volatile int i=0; i < 999; i++) {
114
    if (service == 0) return 0;
115
  };
116
 
117
  return -1;
118 60 sybreon
}
119 46 sybreon
 
120 29 sybreon
/**
121
   FIBONACCI TEST
122
   http://en.literateprograms.org/Fibonacci_numbers_(C)
123 2 sybreon
 
124 29 sybreon
   This tests for the following:
125
   - Recursion & Iteration
126
   - 32/16/8-bit data handling
127
*/
128
 
129
unsigned int fib_slow(unsigned int n)
130 6 sybreon
{
131 29 sybreon
  return n < 2 ? n : fib_slow(n-1) + fib_slow(n-2);
132 6 sybreon
}
133 2 sybreon
 
134 29 sybreon
unsigned int fib_fast(unsigned int n)
135 6 sybreon
{
136
  unsigned int a[3];
137
  unsigned int *p=a;
138
  unsigned int i;
139
 
140
  for(i=0; i<=n; ++i) {
141
    if(i<2) *p=i;
142
    else {
143
      if(p==a) *p=*(a+1)+*(a+2);
144
      else if(p==a+1) *p=*a+*(a+2);
145
      else *p=*a+*(a+1);
146
    }
147
    if(++p>a+2) p=a;
148 2 sybreon
  }
149 6 sybreon
 
150
  return p==a?*(p+2):*(p-1);
151 2 sybreon
}
152
 
153 29 sybreon
int fib_test(int max) {
154 6 sybreon
  unsigned int n;
155 29 sybreon
  unsigned int fast, slow;
156
  // 32-bit LUT
157
  unsigned int fib_lut32[] = {
158
    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233
159
  };
160
  // 16-bit LUT
161
  unsigned short fib_lut16[] = {
162
    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233
163
  };
164
  // 8-bit LUT
165
  unsigned char fib_lut8[] = {
166
    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233
167
  };
168 6 sybreon
 
169 29 sybreon
  for (n=0;n<max;n++) {
170
    slow = fib_slow(n);
171
    fast = fib_fast(n);
172
    if ((slow != fast) ||
173
        (fast != fib_lut32[n]) ||
174
        (fast != fib_lut16[n]) ||
175
        (fast != fib_lut8[n])) {
176
      return -1;
177 6 sybreon
    }
178 22 sybreon
  }
179
  return 0;
180 6 sybreon
}
181 22 sybreon
 
182 29 sybreon
/**
183
   EUCLIDEAN TEST
184
   http://en.literateprograms.org/Euclidean_algorithm_(C)
185
 
186
   This tests for the following:
187
   - Modulo arithmetic
188
   - Goto
189
*/
190
 
191
int euclid_gcd(int a, int b) {
192
  if (b > a) goto b_larger;
193
  while (1) {
194
    a = a % b;
195
    if (a == 0) return b;
196
  b_larger:
197
    b = b % a;
198
    if (b == 0) return a;
199
  }
200
}
201
 
202
int euclid_test(int max)
203
{
204
  int n;
205
  int euclid;
206
  // Random Numbers
207
  int euclid_a[] = {
208
    1804289383, 1681692777, 1957747793, 719885386, 596516649,
209
    1025202362, 783368690, 2044897763, 1365180540, 304089172,
210
    35005211, 294702567, 336465782, 278722862
211
  };
212
  int euclid_b[] = {
213
    846930886, 1714636915, 424238335, 1649760492, 1189641421,
214
    1350490027, 1102520059, 1967513926, 1540383426, 1303455736,
215
    521595368, 1726956429, 861021530, 233665123
216
  };
217
 
218
  // GCD 
219
  int euclid_lut[] = {
220
    1, 1, 1, 2, 1, 1, 1, 1, 6, 4, 1, 3, 2, 1
221
  };
222
 
223
  for (n=0;n<max;n++) {
224
    euclid = euclid_gcd(euclid_a[n],euclid_b[n]);
225
    if (euclid != euclid_lut[n]) {
226
      return -1;
227
    }
228
  }
229
  return 0;
230
}
231
 
232
/**
233
   NEWTON-RHAPSON
234
   http://en.literateprograms.org/Newton-Raphson's_method_for_root_finding_(C)
235
 
236
   This tests for the following:
237
   - Multiplication & Division
238
   - Floating point arithmetic
239
   - Integer to Float conversion
240
*/
241
 
242
float newton_sqrt(float n)
243
{
244
  float x = 0.0;
245
  float xn = 0.0;
246
  int iters = 0;
247
  int i;
248
  for (i = 0; i <= (int)n; ++i)
249
    {
250
      float val = i*i-n;
251
      if (val == 0.0)
252
        return i;
253
      if (val > 0.0)
254
        {
255
          xn = (i+(i-1))/2.0;
256
          break;
257
        }
258
    }
259
  while (!(iters++ >= 100
260
           || x == xn))
261
    {
262
      x = xn;
263
      xn = x - (x * x - n) / (2 * x);
264
    }
265
  return xn;
266
}
267
 
268
int newton_test (int max) {
269
  int n;
270
  float newt;
271
  // 32-bit LUT
272
  float newt_lut[] = {
273
    0.000000000000000000000000,
274
    1.000000000000000000000000,
275
    1.414213538169860839843750,
276
    1.732050776481628417968750,
277
    2.000000000000000000000000,
278
    2.236068010330200195312500,
279
    2.449489831924438476562500,
280
    2.645751237869262695312500,
281
    2.828427076339721679687500,
282
    3.000000000000000000000000,
283
    3.162277698516845703125000,
284
    3.316624879837036132812500,
285
    3.464101552963256835937500,
286
    3.605551242828369140625000,
287
    3.741657495498657226562500
288
  };
289
 
290
  for (n=0;n<max;n++) {
291
    newt = newton_sqrt(n);
292
    if (newt != newt_lut[n]) {
293
      return -1;
294
    }
295
  }
296
  return 0;
297
}
298
 
299 53 sybreon
 
300 29 sybreon
/**
301 53 sybreon
   FSL TEST ROUTINE
302
*/
303
 
304
int fsl_test ()
305
{
306
  // TEST FSL1 ONLY
307
  int FSL = 0xCAFEF00D;
308
 
309
  asm ("PUT %0, RFSL1" :: "r"(FSL));
310
  asm ("GET %0, RFSL1" : "=r"(FSL));
311
 
312 67 sybreon
  if (FSL != 0x01) return -1;
313 53 sybreon
 
314
  asm ("PUT %0, RFSL31" :: "r"(FSL));
315
  asm ("GET %0, RFSL31" : "=r"(FSL));
316
 
317 67 sybreon
  if (FSL != 0x1F) return -1;
318 53 sybreon
 
319
  return 0;
320
}
321
 
322
/**
323 29 sybreon
   MAIN TEST PROGRAMME
324
 
325
   This is the main test procedure. It will output signals onto the
326
   MPI port that is checked by the testbench.
327
 */
328
 
329 42 sybreon
 
330 29 sybreon
int main ()
331
{
332
  // Message Passing Port
333
  int* mpi = (int*)0xFFFFFFFF;
334 42 sybreon
 
335 29 sybreon
  // Number of each test to run
336 46 sybreon
  int max = 10;
337 29 sybreon
 
338 60 sybreon
  // Enable Global Interrupts
339
  int_enable();
340
 
341
  // INT TEST
342
  if (int_test() == -1) { *mpi = 0x4641494C; }
343
 
344 53 sybreon
  // FSL TEST
345
  if (fsl_test() == -1) { *mpi = 0x4641494C; }
346
 
347 29 sybreon
  // Fibonacci Test
348 31 sybreon
  if (fib_test(max) == -1) { *mpi = 0x4641494C; }
349 29 sybreon
 
350
  // Euclid Test
351 31 sybreon
  if (euclid_test(max) == -1) { *mpi = 0x4641494C; }
352 29 sybreon
 
353
  // Newton-Rhapson Test
354 31 sybreon
  if (newton_test(max) == -1) { *mpi = 0x4641494C; }
355 29 sybreon
 
356 42 sybreon
  // Disable Global Interrupts
357
  int_disable();
358 29 sybreon
  // ALL PASSED
359
  return 0;
360
}

powered by: WebSVN 2.1.0

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