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

Subversion Repositories aemb

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

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

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

powered by: WebSVN 2.1.0

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