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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [coremark/] [core_state.c] - Blame information for rev 42

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

Line No. Rev Author Line
1 2 zero_gravi
/*
2
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
3
 
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7
 
8
    http://www.apache.org/licenses/LICENSE-2.0
9
 
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
 
16
Original Author: Shay Gal-on
17
*/
18
 
19
#include "coremark.h"
20
/* local functions */
21 38 zero_gravi
enum CORE_STATE core_state_transition(ee_u8 **instr, ee_u32 *transition_count);
22 2 zero_gravi
 
23
/*
24
Topic: Description
25 38 zero_gravi
        Simple state machines like this one are used in many embedded products.
26
 
27
        For more complex state machines, sometimes a state transition table
28
implementation is used instead, trading speed of direct coding for ease of
29
maintenance.
30
 
31
        Since the main goal of using a state machine in CoreMark is to excercise
32
the switch/if behaviour, we are using a small moore machine.
33
 
34
        In particular, this machine tests type of string input,
35
        trying to determine whether the input is a number or something else.
36
        (see core_state.png).
37 2 zero_gravi
*/
38
 
39
/* Function: core_bench_state
40 38 zero_gravi
        Benchmark function
41 2 zero_gravi
 
42 38 zero_gravi
        Go over the input twice, once direct, and once after introducing some
43
   corruption.
44 2 zero_gravi
*/
45 38 zero_gravi
ee_u16
46
core_bench_state(ee_u32 blksize,
47
                 ee_u8 *memblock,
48
                 ee_s16 seed1,
49
                 ee_s16 seed2,
50
                 ee_s16 step,
51
                 ee_u16 crc)
52 2 zero_gravi
{
53 38 zero_gravi
    ee_u32 final_counts[NUM_CORE_STATES];
54
    ee_u32 track_counts[NUM_CORE_STATES];
55
    ee_u8 *p = memblock;
56
    ee_u32 i;
57 2 zero_gravi
 
58
#if CORE_DEBUG
59 38 zero_gravi
    ee_printf("State Bench: %d,%d,%d,%04x\n", seed1, seed2, step, crc);
60 2 zero_gravi
#endif
61 38 zero_gravi
    for (i = 0; i < NUM_CORE_STATES; i++)
62
    {
63
        final_counts[i] = track_counts[i] = 0;
64
    }
65
    /* run the state machine over the input */
66
    while (*p != 0)
67
    {
68
        enum CORE_STATE fstate = core_state_transition(&p, track_counts);
69
        final_counts[fstate]++;
70 2 zero_gravi
#if CORE_DEBUG
71 38 zero_gravi
        ee_printf("%d,", fstate);
72
    }
73
    ee_printf("\n");
74 2 zero_gravi
#else
75 38 zero_gravi
    }
76 2 zero_gravi
#endif
77 38 zero_gravi
    p = memblock;
78
    while (p < (memblock + blksize))
79
    { /* insert some corruption */
80
        if (*p != ',')
81
            *p ^= (ee_u8)seed1;
82
        p += step;
83
    }
84
    p = memblock;
85
    /* run the state machine over the input again */
86
    while (*p != 0)
87
    {
88
        enum CORE_STATE fstate = core_state_transition(&p, track_counts);
89
        final_counts[fstate]++;
90 2 zero_gravi
#if CORE_DEBUG
91 38 zero_gravi
        ee_printf("%d,", fstate);
92
    }
93
    ee_printf("\n");
94 2 zero_gravi
#else
95 38 zero_gravi
    }
96 2 zero_gravi
#endif
97 38 zero_gravi
    p = memblock;
98
    while (p < (memblock + blksize))
99
    { /* undo corruption is seed1 and seed2 are equal */
100
        if (*p != ',')
101
            *p ^= (ee_u8)seed2;
102
        p += step;
103
    }
104
    /* end timing */
105
    for (i = 0; i < NUM_CORE_STATES; i++)
106
    {
107
        crc = crcu32(final_counts[i], crc);
108
        crc = crcu32(track_counts[i], crc);
109
    }
110
    return crc;
111 2 zero_gravi
}
112
 
113
/* Default initialization patterns */
114 38 zero_gravi
static ee_u8 *intpat[4]
115
    = { (ee_u8 *)"5012", (ee_u8 *)"1234", (ee_u8 *)"-874", (ee_u8 *)"+122" };
116
static ee_u8 *floatpat[4] = { (ee_u8 *)"35.54400",
117
                              (ee_u8 *)".1234500",
118
                              (ee_u8 *)"-110.700",
119
                              (ee_u8 *)"+0.64400" };
120
static ee_u8 *scipat[4]   = { (ee_u8 *)"5.500e+3",
121
                            (ee_u8 *)"-.123e-2",
122
                            (ee_u8 *)"-87e+832",
123
                            (ee_u8 *)"+0.6e-12" };
124
static ee_u8 *errpat[4]   = { (ee_u8 *)"T0.3e-1F",
125
                            (ee_u8 *)"-T.T++Tq",
126
                            (ee_u8 *)"1T3.4e4z",
127
                            (ee_u8 *)"34.0e-T^" };
128 2 zero_gravi
 
129
/* Function: core_init_state
130 38 zero_gravi
        Initialize the input data for the state machine.
131 2 zero_gravi
 
132 38 zero_gravi
        Populate the input with several predetermined strings, interspersed.
133
        Actual patterns chosen depend on the seed parameter.
134
 
135
        Note:
136
        The seed parameter MUST be supplied from a source that cannot be
137
   determined at compile time
138 2 zero_gravi
*/
139 38 zero_gravi
void
140
core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p)
141
{
142
    ee_u32 total = 0, next = 0, i;
143
    ee_u8 *buf = 0;
144 2 zero_gravi
#if CORE_DEBUG
145 38 zero_gravi
    ee_u8 *start = p;
146
    ee_printf("State: %d,%d\n", size, seed);
147 2 zero_gravi
#endif
148 38 zero_gravi
    size--;
149
    next = 0;
150
    while ((total + next + 1) < size)
151
    {
152
        if (next > 0)
153
        {
154
            for (i = 0; i < next; i++)
155
                *(p + total + i) = buf[i];
156
            *(p + total + i) = ',';
157
            total += next + 1;
158
        }
159
        seed++;
160
        switch (seed & 0x7)
161
        {
162
            case 0: /* int */
163
            case 1: /* int */
164
            case 2: /* int */
165
                buf  = intpat[(seed >> 3) & 0x3];
166
                next = 4;
167
                break;
168
            case 3: /* float */
169
            case 4: /* float */
170
                buf  = floatpat[(seed >> 3) & 0x3];
171
                next = 8;
172
                break;
173
            case 5: /* scientific */
174
            case 6: /* scientific */
175
                buf  = scipat[(seed >> 3) & 0x3];
176
                next = 8;
177
                break;
178
            case 7: /* invalid */
179
                buf  = errpat[(seed >> 3) & 0x3];
180
                next = 8;
181
                break;
182
            default: /* Never happen, just to make some compilers happy */
183
                break;
184
        }
185
    }
186
    size++;
187
    while (total < size)
188
    { /* fill the rest with 0 */
189
        *(p + total) = 0;
190
        total++;
191
    }
192 2 zero_gravi
#if CORE_DEBUG
193 38 zero_gravi
    ee_printf("State Input: %s\n", start);
194 2 zero_gravi
#endif
195
}
196
 
197 38 zero_gravi
static ee_u8
198
ee_isdigit(ee_u8 c)
199
{
200
    ee_u8 retval;
201
    retval = ((c >= '0') & (c <= '9')) ? 1 : 0;
202
    return retval;
203 2 zero_gravi
}
204
 
205
/* Function: core_state_transition
206 38 zero_gravi
        Actual state machine.
207 2 zero_gravi
 
208 38 zero_gravi
        The state machine will continue scanning until either:
209
        1 - an invalid input is detcted.
210
        2 - a valid number has been detected.
211
 
212
        The input pointer is updated to point to the end of the token, and the
213
   end state is returned (either specific format determined or invalid).
214 2 zero_gravi
*/
215
 
216 38 zero_gravi
enum CORE_STATE
217
core_state_transition(ee_u8 **instr, ee_u32 *transition_count)
218
{
219
    ee_u8 *         str = *instr;
220
    ee_u8           NEXT_SYMBOL;
221
    enum CORE_STATE state = CORE_START;
222
    for (; *str && state != CORE_INVALID; str++)
223
    {
224
        NEXT_SYMBOL = *str;
225
        if (NEXT_SYMBOL == ',') /* end of this input */
226
        {
227
            str++;
228
            break;
229
        }
230
        switch (state)
231
        {
232
            case CORE_START:
233
                if (ee_isdigit(NEXT_SYMBOL))
234
                {
235
                    state = CORE_INT;
236
                }
237
                else if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-')
238
                {
239
                    state = CORE_S1;
240
                }
241
                else if (NEXT_SYMBOL == '.')
242
                {
243
                    state = CORE_FLOAT;
244
                }
245
                else
246
                {
247
                    state = CORE_INVALID;
248
                    transition_count[CORE_INVALID]++;
249
                }
250
                transition_count[CORE_START]++;
251
                break;
252
            case CORE_S1:
253
                if (ee_isdigit(NEXT_SYMBOL))
254
                {
255
                    state = CORE_INT;
256
                    transition_count[CORE_S1]++;
257
                }
258
                else if (NEXT_SYMBOL == '.')
259
                {
260
                    state = CORE_FLOAT;
261
                    transition_count[CORE_S1]++;
262
                }
263
                else
264
                {
265
                    state = CORE_INVALID;
266
                    transition_count[CORE_S1]++;
267
                }
268
                break;
269
            case CORE_INT:
270
                if (NEXT_SYMBOL == '.')
271
                {
272
                    state = CORE_FLOAT;
273
                    transition_count[CORE_INT]++;
274
                }
275
                else if (!ee_isdigit(NEXT_SYMBOL))
276
                {
277
                    state = CORE_INVALID;
278
                    transition_count[CORE_INT]++;
279
                }
280
                break;
281
            case CORE_FLOAT:
282
                if (NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e')
283
                {
284
                    state = CORE_S2;
285
                    transition_count[CORE_FLOAT]++;
286
                }
287
                else if (!ee_isdigit(NEXT_SYMBOL))
288
                {
289
                    state = CORE_INVALID;
290
                    transition_count[CORE_FLOAT]++;
291
                }
292
                break;
293
            case CORE_S2:
294
                if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-')
295
                {
296
                    state = CORE_EXPONENT;
297
                    transition_count[CORE_S2]++;
298
                }
299
                else
300
                {
301
                    state = CORE_INVALID;
302
                    transition_count[CORE_S2]++;
303
                }
304
                break;
305
            case CORE_EXPONENT:
306
                if (ee_isdigit(NEXT_SYMBOL))
307
                {
308
                    state = CORE_SCIENTIFIC;
309
                    transition_count[CORE_EXPONENT]++;
310
                }
311
                else
312
                {
313
                    state = CORE_INVALID;
314
                    transition_count[CORE_EXPONENT]++;
315
                }
316
                break;
317
            case CORE_SCIENTIFIC:
318
                if (!ee_isdigit(NEXT_SYMBOL))
319
                {
320
                    state = CORE_INVALID;
321
                    transition_count[CORE_INVALID]++;
322
                }
323
                break;
324
            default:
325
                break;
326
        }
327
    }
328
    *instr = str;
329
    return state;
330 2 zero_gravi
}

powered by: WebSVN 2.1.0

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