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

Subversion Repositories aemb

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

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

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

powered by: WebSVN 2.1.0

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