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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [kernel/] [v2_0/] [tests/] [fptest.c] - Blame information for rev 510

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        fptest.cxx
4
//
5
//        Basic FPU test
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 2003 Nick Garnett
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// -------------------------------------------
37
//####ECOSGPLCOPYRIGHTEND####
38
//==========================================================================
39
//#####DESCRIPTIONBEGIN####
40
//
41
// Author(s):     nickg@calivar.com
42
// Contributors:  nickg@calivar.com
43
// Date:          2003-01-27
44
// Description:   Simple FPU test. This is not very sophisticated as far
45
//                as checking FPU performance or accuracy. It is more
46
//                concerned with checking that several threads doing FP
47
//                operations do not interfere with eachother's use of the
48
//                FPU.
49
//
50
//####DESCRIPTIONEND####
51
//==========================================================================
52
 
53
#include <pkgconf/kernel.h>
54
#include <pkgconf/hal.h>
55
 
56
#include <cyg/hal/hal_arch.h>
57
 
58
#include <cyg/kernel/kapi.h>
59
 
60
#include <cyg/infra/testcase.h>
61
#include <cyg/infra/diag.h>
62
 
63
//#include <cyg/kernel/test/stackmon.h>
64
//#include CYGHWR_MEMORY_LAYOUT_H
65
 
66
//==========================================================================
67
 
68
#if defined(CYGFUN_KERNEL_API_C) &&             \
69
    defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&     \
70
    (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
71
 
72
//==========================================================================
73
// Base priority for all threads.
74
 
75
#define BASE_PRI        5
76
 
77
//==========================================================================
78
// Runtime
79
//
80
// This is the number of ticks that the program will run for. 3000
81
// ticks is equal to 30 seconds in the default configuration. For
82
// simulators we reduce the run time to 3 simulated seconds.
83
 
84
#define RUN_TICKS       3000
85
#define RUN_TICKS_SIM   300
86
 
87
//==========================================================================
88
// Thread parameters
89
 
90
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_MINIMUM)
91
 
92
static cyg_uint8 stacks[3][STACK_SIZE];
93
static cyg_handle_t thread[3];
94
static cyg_thread thread_struct[3];
95
 
96
//==========================================================================
97
// Alarm parameters.
98
 
99
static cyg_alarm alarm_struct;
100
static cyg_handle_t alarm;
101
 
102
static cyg_count8 cur_thread = 0;
103
static cyg_count32 alarm_ticks = 0;
104
static cyg_count32 run_ticks = RUN_TICKS;
105
 
106
//==========================================================================
107
 
108
static int errors = 0;
109
 
110
//==========================================================================
111
// Random number generator. Ripped out of the C library.
112
 
113
static int rand( unsigned int *seed )
114
{
115
// This is the code supplied in Knuth Vol 2 section 3.6 p.185 bottom
116
 
117
#define RAND_MAX 0x7fffffff
118
#define MM 2147483647    // a Mersenne prime
119
#define AA 48271         // this does well in the spectral test
120
#define QQ 44488         // (long)(MM/AA)
121
#define RR 3399          // MM % AA; it is important that RR<QQ
122
 
123
    *seed = AA*(*seed % QQ) - RR*(unsigned int)(*seed/QQ);
124
    if (*seed < 0)
125
        *seed += MM;
126
 
127
    return (int)( *seed & RAND_MAX );
128
}
129
 
130
//==========================================================================
131
// Test calculation.
132
//
133
// Generates an array of random FP values and then repeatedly applies
134
// a calculation to them and checks that the same result is reached
135
// each time. The calculation, in the macro CALC, is intended to make
136
// maximum use of the FPU registers. However, the i386 compiler
137
// doesn't let this expression get very complex before it starts
138
// spilling values out to memory.
139
 
140
static void do_test( double *values,
141
                     int count,
142
                     int loops,
143
                     int test,
144
                     const char *name)
145
{
146
    unsigned int i, j;
147
    // volatiles necessary to force
148
    // values to 64 bits for comparison
149
    volatile double sum = 1.0;
150
    volatile double last_sum;
151
    unsigned int seed;
152
 
153
#define V(__i) (values[(__i)%count])
154
#define CALC ((V(i-1)*V(i+1))*(V(i-2)*V(i+2))*(V(i-3)*sum))
155
 
156
    seed = ((unsigned int)&i)*count;
157
 
158
    // Set up an array of values...
159
    for( i = 0; i < count; i++ )
160
        values[i] = (double)rand( &seed )/(double)0x7fffffff;
161
 
162
    // Now calculate something from them...
163
    for( i = 0; i < count; i++ )
164
        sum += CALC;
165
    last_sum = sum;
166
 
167
    // Now recalculate the sum in a loop and look for errors
168
    for( j = 0; j < loops ; j++ )
169
    {
170
        sum = 1.0;
171
        for( i = 0; i < count; i++ )
172
            sum += CALC;
173
 
174
        if( sum != last_sum )
175
        {
176
            errors++;
177
            diag_printf("%s: Sum mismatch! %d sum=[%08x:%08x] last_sum=[%08x:%08x]\n",
178
                        name,j,
179
                        ((cyg_uint32 *)&sum)[0],((cyg_uint32 *)&sum)[1],
180
                        ((cyg_uint32 *)&last_sum)[0],((cyg_uint32 *)&last_sum)[1]
181
                        );
182
        }
183
 
184
#if 0
185
        if( ((j*count)%1000000) == 0 )
186
            diag_printf("INFO:<%s: %2d calculations done>\n",name,j*count);
187
#endif
188
    }
189
 
190
}
191
 
192
//==========================================================================
193
// Alarm handler
194
//
195
// This is called every tick. It lowers the priority of the currently
196
// running thread and raises the priority of the next. Thus we
197
// implement a form of timelslicing between the threads at one tick
198
// granularity.
199
 
200
static void alarm_fn(cyg_handle_t alarm, cyg_addrword_t data)
201
{
202
    alarm_ticks++;
203
 
204
    if( alarm_ticks >= run_ticks )
205
    {
206
        if( errors )
207
            CYG_TEST_FAIL("Errors detected");
208
        else
209
            CYG_TEST_PASS("OK");
210
 
211
        CYG_TEST_FINISH("FP Test done");
212
    }
213
    else
214
    {
215
        cyg_thread_set_priority( thread[cur_thread], BASE_PRI );
216
 
217
        cur_thread = (cur_thread+1)%3;
218
 
219
        cyg_thread_set_priority( thread[cur_thread], BASE_PRI-1 );
220
    }
221
}
222
 
223
 
224
//==========================================================================
225
 
226
#define FP1_COUNT 1000
227
 
228
static double fpt1_values[FP1_COUNT];
229
 
230
void fptest1( CYG_ADDRWORD id )
231
{
232
    while(1)
233
        do_test( fpt1_values, FP1_COUNT, 2000000000, id, "fptest1" );
234
}
235
 
236
//==========================================================================
237
 
238
#define FP2_COUNT 10000
239
 
240
static double fpt2_values[FP2_COUNT];
241
 
242
void fptest2( CYG_ADDRWORD id )
243
{
244
    while(1)
245
        do_test( fpt2_values, FP2_COUNT, 2000000000, id, "fptest2" );
246
}
247
 
248
//==========================================================================
249
 
250
#define FP3_COUNT 100
251
 
252
static double fpt3_values[FP3_COUNT];
253
 
254
void fptest3( CYG_ADDRWORD id )
255
{
256
    while(1)
257
        do_test( fpt3_values, FP3_COUNT, 2000000000, id, "fptest3" );
258
}
259
 
260
//==========================================================================
261
 
262
void fptest_main( void )
263
{
264
 
265
    CYG_TEST_INIT();
266
 
267
    if( cyg_test_is_simulator )
268
    {
269
        run_ticks = RUN_TICKS_SIM;
270
    }
271
 
272
    CYG_TEST_INFO("Run fptest in cyg_start");
273
    do_test( fpt3_values, FP3_COUNT, 1000, 0, "start" );
274
    CYG_TEST_INFO( "cyg_start run done");
275
 
276
    cyg_thread_create( BASE_PRI-1,
277
                       fptest1,
278
                       0,
279
                       "fptest1",
280
                       &stacks[0][0],
281
                       STACK_SIZE,
282
                       &thread[0],
283
                       &thread_struct[0]);
284
 
285
    cyg_thread_resume( thread[0] );
286
 
287
    cyg_thread_create( BASE_PRI,
288
                       fptest2,
289
                       1,
290
                       "fptest2",
291
                       &stacks[1][0],
292
                       STACK_SIZE,
293
                       &thread[1],
294
                       &thread_struct[1]);
295
 
296
    cyg_thread_resume( thread[1] );
297
 
298
    cyg_thread_create( BASE_PRI,
299
                       fptest3,
300
                       2,
301
                       "fptest3",
302
                       &stacks[2][0],
303
                       STACK_SIZE,
304
                       &thread[2],
305
                       &thread_struct[2]);
306
 
307
    cyg_thread_resume( thread[2] );
308
 
309
    cyg_alarm_create( cyg_real_time_clock(),
310
                      alarm_fn,
311
                      0,
312
                      &alarm,
313
                      &alarm_struct );
314
 
315
    cyg_alarm_initialize( alarm, cyg_current_time()+1, 1 );
316
 
317
    cyg_scheduler_start();
318
 
319
}
320
 
321
//==========================================================================
322
 
323
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
324
externC void
325
cyg_hal_invoke_constructors();
326
#endif
327
 
328
externC void
329
cyg_start( void )
330
{
331
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
332
    cyg_hal_invoke_constructors();
333
#endif
334
    fptest_main();
335
}
336
 
337
//==========================================================================
338
 
339
#else // CYGFUN_KERNEL_API_C...
340
 
341
externC void
342
cyg_start( void )
343
{
344
    CYG_TEST_INIT();
345
    CYG_TEST_NA("FP test requires:\n"
346
                "CYGFUN_KERNEL_API_C && \n"
347
                "CYGSEM_KERNEL_SCHED_MLQUEUE && \n"
348
                "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
349
}
350
 
351
#endif // CYGFUN_KERNEL_API_C, etc.
352
 
353
//==========================================================================
354
// EOF fptest.cxx

powered by: WebSVN 2.1.0

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