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

Subversion Repositories neorv32

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

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
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
22
 
23
/*
24
Topic: Description
25
        Simple state machines like this one are used in many embedded products.
26
 
27
        For more complex state machines, sometimes a state transition table implementation is used instead,
28
        trading speed of direct coding for ease of maintenance.
29
 
30
        Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
31
        we are using a small moore machine.
32
 
33
        In particular, this machine tests type of string input,
34
        trying to determine whether the input is a number or something else.
35
        (see core_state.png).
36
*/
37
 
38
/* Function: core_bench_state
39
        Benchmark function
40
 
41
        Go over the input twice, once direct, and once after introducing some corruption.
42
*/
43
ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
44
                ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
45
{
46
        ee_u32 final_counts[NUM_CORE_STATES];
47
        ee_u32 track_counts[NUM_CORE_STATES];
48
        ee_u8 *p=memblock;
49
        ee_u32 i;
50
 
51
 
52
#if CORE_DEBUG
53
        ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
54
#endif
55
        for (i=0; i<NUM_CORE_STATES; i++) {
56
                final_counts[i]=track_counts[i]=0;
57
        }
58
        /* run the state machine over the input */
59
        while (*p!=0) {
60
                enum CORE_STATE fstate=core_state_transition(&p,track_counts);
61
                final_counts[fstate]++;
62
#if CORE_DEBUG
63
        ee_printf("%d,",fstate);
64
        }
65
        ee_printf("\n");
66
#else
67
        }
68
#endif
69
        p=memblock;
70
        while (p < (memblock+blksize)) { /* insert some corruption */
71
                if (*p!=',')
72
                        *p^=(ee_u8)seed1;
73
                p+=step;
74
        }
75
        p=memblock;
76
        /* run the state machine over the input again */
77
        while (*p!=0) {
78
                enum CORE_STATE fstate=core_state_transition(&p,track_counts);
79
                final_counts[fstate]++;
80
#if CORE_DEBUG
81
        ee_printf("%d,",fstate);
82
        }
83
        ee_printf("\n");
84
#else
85
        }
86
#endif
87
        p=memblock;
88
        while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
89
                if (*p!=',')
90
                        *p^=(ee_u8)seed2;
91
                p+=step;
92
        }
93
        /* end timing */
94
        for (i=0; i<NUM_CORE_STATES; i++) {
95
                crc=crcu32(final_counts[i],crc);
96
                crc=crcu32(track_counts[i],crc);
97
        }
98
        return crc;
99
}
100
 
101
/* Default initialization patterns */
102
static ee_u8 *intpat[4]  ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
103
static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
104
static ee_u8 *scipat[4]  ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
105
static ee_u8 *errpat[4]  ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
106
 
107
/* Function: core_init_state
108
        Initialize the input data for the state machine.
109
 
110
        Populate the input with several predetermined strings, interspersed.
111
        Actual patterns chosen depend on the seed parameter.
112
 
113
        Note:
114
        The seed parameter MUST be supplied from a source that cannot be determined at compile time
115
*/
116
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
117
        ee_u32 total=0,next=0,i;
118
        ee_u8 *buf=0;
119
#if CORE_DEBUG
120
        ee_u8 *start=p;
121
        ee_printf("State: %d,%d\n",size,seed);
122
#endif
123
        size--;
124
        next=0;
125
        while ((total+next+1)<size) {
126
                if (next>0) {
127
                        for(i=0;i<next;i++)
128
                                *(p+total+i)=buf[i];
129
                        *(p+total+i)=',';
130
                        total+=next+1;
131
                }
132
                seed++;
133
                switch (seed & 0x7) {
134
                        case 0: /* int */
135
                        case 1: /* int */
136
                        case 2: /* int */
137
                                buf=intpat[(seed>>3) & 0x3];
138
                                next=4;
139
                        break;
140
                        case 3: /* float */
141
                        case 4: /* float */
142
                                buf=floatpat[(seed>>3) & 0x3];
143
                                next=8;
144
                        break;
145
                        case 5: /* scientific */
146
                        case 6: /* scientific */
147
                                buf=scipat[(seed>>3) & 0x3];
148
                                next=8;
149
                        break;
150
                        case 7: /* invalid */
151
                                buf=errpat[(seed>>3) & 0x3];
152
                                next=8;
153
                        break;
154
                        default: /* Never happen, just to make some compilers happy */
155
                        break;
156
                }
157
        }
158
        size++;
159
        while (total<size) { /* fill the rest with 0 */
160
                *(p+total)=0;
161
                total++;
162
        }
163
#if CORE_DEBUG
164
        ee_printf("State Input: %s\n",start);
165
#endif
166
}
167
 
168
static ee_u8 ee_isdigit(ee_u8 c) {
169
        ee_u8 retval;
170
        retval = ((c>='0') & (c<='9')) ? 1 : 0;
171
        return retval;
172
}
173
 
174
/* Function: core_state_transition
175
        Actual state machine.
176
 
177
        The state machine will continue scanning until either:
178
        1 - an invalid input is detcted.
179
        2 - a valid number has been detected.
180
 
181
        The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid).
182
*/
183
 
184
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
185
        ee_u8 *str=*instr;
186
        ee_u8 NEXT_SYMBOL;
187
        enum CORE_STATE state=CORE_START;
188
        for( ; *str && state != CORE_INVALID; str++ ) {
189
                NEXT_SYMBOL = *str;
190
                if (NEXT_SYMBOL==',') /* end of this input */ {
191
                        str++;
192
                        break;
193
                }
194
                switch(state) {
195
                case CORE_START:
196
                        if(ee_isdigit(NEXT_SYMBOL)) {
197
                                state = CORE_INT;
198
                        }
199
                        else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
200
                                state = CORE_S1;
201
                        }
202
                        else if( NEXT_SYMBOL == '.' ) {
203
                                state = CORE_FLOAT;
204
                        }
205
                        else {
206
                                state = CORE_INVALID;
207
                                transition_count[CORE_INVALID]++;
208
                        }
209
                        transition_count[CORE_START]++;
210
                        break;
211
                case CORE_S1:
212
                        if(ee_isdigit(NEXT_SYMBOL)) {
213
                                state = CORE_INT;
214
                                transition_count[CORE_S1]++;
215
                        }
216
                        else if( NEXT_SYMBOL == '.' ) {
217
                                state = CORE_FLOAT;
218
                                transition_count[CORE_S1]++;
219
                        }
220
                        else {
221
                                state = CORE_INVALID;
222
                                transition_count[CORE_S1]++;
223
                        }
224
                        break;
225
                case CORE_INT:
226
                        if( NEXT_SYMBOL == '.' ) {
227
                                state = CORE_FLOAT;
228
                                transition_count[CORE_INT]++;
229
                        }
230
                        else if(!ee_isdigit(NEXT_SYMBOL)) {
231
                                state = CORE_INVALID;
232
                                transition_count[CORE_INT]++;
233
                        }
234
                        break;
235
                case CORE_FLOAT:
236
                        if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
237
                                state = CORE_S2;
238
                                transition_count[CORE_FLOAT]++;
239
                        }
240
                        else if(!ee_isdigit(NEXT_SYMBOL)) {
241
                                state = CORE_INVALID;
242
                                transition_count[CORE_FLOAT]++;
243
                        }
244
                        break;
245
                case CORE_S2:
246
                        if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
247
                                state = CORE_EXPONENT;
248
                                transition_count[CORE_S2]++;
249
                        }
250
                        else {
251
                                state = CORE_INVALID;
252
                                transition_count[CORE_S2]++;
253
                        }
254
                        break;
255
                case CORE_EXPONENT:
256
                        if(ee_isdigit(NEXT_SYMBOL)) {
257
                                state = CORE_SCIENTIFIC;
258
                                transition_count[CORE_EXPONENT]++;
259
                        }
260
                        else {
261
                                state = CORE_INVALID;
262
                                transition_count[CORE_EXPONENT]++;
263
                        }
264
                        break;
265
                case CORE_SCIENTIFIC:
266
                        if(!ee_isdigit(NEXT_SYMBOL)) {
267
                                state = CORE_INVALID;
268
                                transition_count[CORE_INVALID]++;
269
                        }
270
                        break;
271
                default:
272
                        break;
273
                }
274
        }
275
        *instr=str;
276
        return state;
277
}

powered by: WebSVN 2.1.0

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