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

Subversion Repositories aemb

[/] [aemb/] [trunk/] [sw/] [c/] [aeMB_testbench.c] - Blame information for rev 64

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

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

powered by: WebSVN 2.1.0

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