source: soft/giet_vm/applications/coremark/core_state.c

Last change on this file was 753, checked in by cfuguet, 9 years ago

Introducing the coremark benchmark

File size: 7.0 KB
Line 
1/*
2Author : Shay Gal-On, EEMBC
3
4This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
5All rights reserved.                           
6
7EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
8CoreMark License that is distributed with the official EEMBC COREMARK Software release.
9If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
10you must discontinue use and download the official release from www.coremark.org. 
11
12Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
13make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
14
15EEMBC
164354 Town Center Blvd. Suite 114-200
17El Dorado Hills, CA, 95762
18*/ 
19#include "coremark.h"
20/* local functions */
21enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
22
23/*
24Topic: 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*/
43ee_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 */
102static ee_u8 *intpat[4]  ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
103static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
104static ee_u8 *scipat[4]  ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
105static 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*/
116void 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
168static 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
184enum 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}
Note: See TracBrowser for help on using the repository browser.