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

Subversion Repositories aemb

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

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

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

powered by: WebSVN 2.1.0

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