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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [coremark/] [core_state.c] - Diff between revs 2 and 38

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 38
Line 22... Line 22...
 
 
/*
/*
Topic: Description
Topic: Description
        Simple state machines like this one are used in many embedded products.
        Simple state machines like this one are used in many embedded products.
 
 
        For more complex state machines, sometimes a state transition table implementation is used instead,
        For more complex state machines, sometimes a state transition table
        trading speed of direct coding for ease of maintenance.
implementation is used instead, trading speed of direct coding for ease of
 
maintenance.
 
 
        Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
        Since the main goal of using a state machine in CoreMark is to excercise
        we are using a small moore machine.
the switch/if behaviour, we are using a small moore machine.
 
 
        In particular, this machine tests type of string input,
        In particular, this machine tests type of string input,
        trying to determine whether the input is a number or something else.
        trying to determine whether the input is a number or something else.
        (see core_state.png).
        (see core_state.png).
*/
*/
 
 
/* Function: core_bench_state
/* Function: core_bench_state
        Benchmark function
        Benchmark function
 
 
        Go over the input twice, once direct, and once after introducing some corruption.
        Go over the input twice, once direct, and once after introducing some
 
   corruption.
*/
*/
ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
ee_u16
                ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
core_bench_state(ee_u32 blksize,
 
                 ee_u8 *memblock,
 
                 ee_s16 seed1,
 
                 ee_s16 seed2,
 
                 ee_s16 step,
 
                 ee_u16 crc)
{
{
        ee_u32 final_counts[NUM_CORE_STATES];
        ee_u32 final_counts[NUM_CORE_STATES];
        ee_u32 track_counts[NUM_CORE_STATES];
        ee_u32 track_counts[NUM_CORE_STATES];
        ee_u8 *p=memblock;
        ee_u8 *p=memblock;
        ee_u32 i;
        ee_u32 i;
 
 
 
 
#if CORE_DEBUG
#if CORE_DEBUG
        ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
        ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
#endif
#endif
        for (i=0; i<NUM_CORE_STATES; i++) {
    for (i = 0; i < NUM_CORE_STATES; i++)
 
    {
                final_counts[i]=track_counts[i]=0;
                final_counts[i]=track_counts[i]=0;
        }
        }
        /* run the state machine over the input */
        /* run the state machine over the input */
        while (*p!=0) {
    while (*p != 0)
 
    {
                enum CORE_STATE fstate=core_state_transition(&p,track_counts);
                enum CORE_STATE fstate=core_state_transition(&p,track_counts);
                final_counts[fstate]++;
                final_counts[fstate]++;
#if CORE_DEBUG
#if CORE_DEBUG
        ee_printf("%d,",fstate);
        ee_printf("%d,",fstate);
        }
        }
        ee_printf("\n");
        ee_printf("\n");
#else
#else
        }
        }
#endif
#endif
        p=memblock;
        p=memblock;
        while (p < (memblock+blksize)) { /* insert some corruption */
    while (p < (memblock + blksize))
 
    { /* insert some corruption */
                if (*p!=',')
                if (*p!=',')
                        *p^=(ee_u8)seed1;
                        *p^=(ee_u8)seed1;
                p+=step;
                p+=step;
        }
        }
        p=memblock;
        p=memblock;
        /* run the state machine over the input again */
        /* run the state machine over the input again */
        while (*p!=0) {
    while (*p != 0)
 
    {
                enum CORE_STATE fstate=core_state_transition(&p,track_counts);
                enum CORE_STATE fstate=core_state_transition(&p,track_counts);
                final_counts[fstate]++;
                final_counts[fstate]++;
#if CORE_DEBUG
#if CORE_DEBUG
        ee_printf("%d,",fstate);
        ee_printf("%d,",fstate);
        }
        }
        ee_printf("\n");
        ee_printf("\n");
#else
#else
        }
        }
#endif
#endif
        p=memblock;
        p=memblock;
        while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
    while (p < (memblock + blksize))
 
    { /* undo corruption is seed1 and seed2 are equal */
                if (*p!=',')
                if (*p!=',')
                        *p^=(ee_u8)seed2;
                        *p^=(ee_u8)seed2;
                p+=step;
                p+=step;
        }
        }
        /* end timing */
        /* end timing */
        for (i=0; i<NUM_CORE_STATES; i++) {
    for (i = 0; i < NUM_CORE_STATES; i++)
 
    {
                crc=crcu32(final_counts[i],crc);
                crc=crcu32(final_counts[i],crc);
                crc=crcu32(track_counts[i],crc);
                crc=crcu32(track_counts[i],crc);
        }
        }
        return crc;
        return crc;
}
}
 
 
/* Default initialization patterns */
/* Default initialization patterns */
static ee_u8 *intpat[4]  ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
static ee_u8 *intpat[4]
static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
    = { (ee_u8 *)"5012", (ee_u8 *)"1234", (ee_u8 *)"-874", (ee_u8 *)"+122" };
static ee_u8 *scipat[4]  ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
static ee_u8 *floatpat[4] = { (ee_u8 *)"35.54400",
static ee_u8 *errpat[4]  ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
                              (ee_u8 *)".1234500",
 
                              (ee_u8 *)"-110.700",
 
                              (ee_u8 *)"+0.64400" };
 
static ee_u8 *scipat[4]   = { (ee_u8 *)"5.500e+3",
 
                            (ee_u8 *)"-.123e-2",
 
                            (ee_u8 *)"-87e+832",
 
                            (ee_u8 *)"+0.6e-12" };
 
static ee_u8 *errpat[4]   = { (ee_u8 *)"T0.3e-1F",
 
                            (ee_u8 *)"-T.T++Tq",
 
                            (ee_u8 *)"1T3.4e4z",
 
                            (ee_u8 *)"34.0e-T^" };
 
 
/* Function: core_init_state
/* Function: core_init_state
        Initialize the input data for the state machine.
        Initialize the input data for the state machine.
 
 
        Populate the input with several predetermined strings, interspersed.
        Populate the input with several predetermined strings, interspersed.
        Actual patterns chosen depend on the seed parameter.
        Actual patterns chosen depend on the seed parameter.
 
 
        Note:
        Note:
        The seed parameter MUST be supplied from a source that cannot be determined at compile time
        The seed parameter MUST be supplied from a source that cannot be
 
   determined at compile time
*/
*/
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
void
 
core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p)
 
{
        ee_u32 total=0,next=0,i;
        ee_u32 total=0,next=0,i;
        ee_u8 *buf=0;
        ee_u8 *buf=0;
#if CORE_DEBUG
#if CORE_DEBUG
        ee_u8 *start=p;
        ee_u8 *start=p;
        ee_printf("State: %d,%d\n",size,seed);
        ee_printf("State: %d,%d\n",size,seed);
#endif
#endif
        size--;
        size--;
        next=0;
        next=0;
        while ((total+next+1)<size) {
    while ((total + next + 1) < size)
                if (next>0) {
    {
 
        if (next > 0)
 
        {
                        for(i=0;i<next;i++)
                        for(i=0;i<next;i++)
                                *(p+total+i)=buf[i];
                                *(p+total+i)=buf[i];
                        *(p+total+i)=',';
                        *(p+total+i)=',';
                        total+=next+1;
                        total+=next+1;
                }
                }
                seed++;
                seed++;
                switch (seed & 0x7) {
        switch (seed & 0x7)
 
        {
                        case 0: /* int */
                        case 0: /* int */
                        case 1: /* int */
                        case 1: /* int */
                        case 2: /* int */
                        case 2: /* int */
                                buf=intpat[(seed>>3) & 0x3];
                                buf=intpat[(seed>>3) & 0x3];
                                next=4;
                                next=4;
Line 154... Line 182...
                        default: /* Never happen, just to make some compilers happy */
                        default: /* Never happen, just to make some compilers happy */
                        break;
                        break;
                }
                }
        }
        }
        size++;
        size++;
        while (total<size) { /* fill the rest with 0 */
    while (total < size)
 
    { /* fill the rest with 0 */
                *(p+total)=0;
                *(p+total)=0;
                total++;
                total++;
        }
        }
#if CORE_DEBUG
#if CORE_DEBUG
        ee_printf("State Input: %s\n",start);
        ee_printf("State Input: %s\n",start);
#endif
#endif
}
}
 
 
static ee_u8 ee_isdigit(ee_u8 c) {
static ee_u8
 
ee_isdigit(ee_u8 c)
 
{
        ee_u8 retval;
        ee_u8 retval;
        retval = ((c>='0') & (c<='9')) ? 1 : 0;
        retval = ((c>='0') & (c<='9')) ? 1 : 0;
        return retval;
        return retval;
}
}
 
 
Line 176... Line 207...
 
 
        The state machine will continue scanning until either:
        The state machine will continue scanning until either:
        1 - an invalid input is detcted.
        1 - an invalid input is detcted.
        2 - a valid number has been detected.
        2 - a valid number has been detected.
 
 
        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).
        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).
*/
*/
 
 
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
enum CORE_STATE
        ee_u8 *str=*instr;
core_state_transition(ee_u8 **instr, ee_u32 *transition_count)
 
{
 
    ee_u8 *         str = *instr;
        ee_u8 NEXT_SYMBOL;
        ee_u8 NEXT_SYMBOL;
        enum CORE_STATE state=CORE_START;
        enum CORE_STATE state=CORE_START;
        for( ; *str && state != CORE_INVALID; str++ ) {
    for (; *str && state != CORE_INVALID; str++)
 
    {
                NEXT_SYMBOL = *str;
                NEXT_SYMBOL = *str;
                if (NEXT_SYMBOL==',') /* end of this input */ {
        if (NEXT_SYMBOL == ',') /* end of this input */
 
        {
                        str++;
                        str++;
                        break;
                        break;
                }
                }
                switch(state) {
        switch (state)
 
        {
                case CORE_START:
                case CORE_START:
                        if(ee_isdigit(NEXT_SYMBOL)) {
                if (ee_isdigit(NEXT_SYMBOL))
 
                {
                                state = CORE_INT;
                                state = CORE_INT;
                        }
                        }
                        else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
                else if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-')
 
                {
                                state = CORE_S1;
                                state = CORE_S1;
                        }
                        }
                        else if( NEXT_SYMBOL == '.' ) {
                else if (NEXT_SYMBOL == '.')
 
                {
                                state = CORE_FLOAT;
                                state = CORE_FLOAT;
                        }
                        }
                        else {
                else
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_INVALID]++;
                                transition_count[CORE_INVALID]++;
                        }
                        }
                        transition_count[CORE_START]++;
                        transition_count[CORE_START]++;
                        break;
                        break;
                case CORE_S1:
                case CORE_S1:
                        if(ee_isdigit(NEXT_SYMBOL)) {
                if (ee_isdigit(NEXT_SYMBOL))
 
                {
                                state = CORE_INT;
                                state = CORE_INT;
                                transition_count[CORE_S1]++;
                                transition_count[CORE_S1]++;
                        }
                        }
                        else if( NEXT_SYMBOL == '.' ) {
                else if (NEXT_SYMBOL == '.')
 
                {
                                state = CORE_FLOAT;
                                state = CORE_FLOAT;
                                transition_count[CORE_S1]++;
                                transition_count[CORE_S1]++;
                        }
                        }
                        else {
                else
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_S1]++;
                                transition_count[CORE_S1]++;
                        }
                        }
                        break;
                        break;
                case CORE_INT:
                case CORE_INT:
                        if( NEXT_SYMBOL == '.' ) {
                if (NEXT_SYMBOL == '.')
 
                {
                                state = CORE_FLOAT;
                                state = CORE_FLOAT;
                                transition_count[CORE_INT]++;
                                transition_count[CORE_INT]++;
                        }
                        }
                        else if(!ee_isdigit(NEXT_SYMBOL)) {
                else if (!ee_isdigit(NEXT_SYMBOL))
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_INT]++;
                                transition_count[CORE_INT]++;
                        }
                        }
                        break;
                        break;
                case CORE_FLOAT:
                case CORE_FLOAT:
                        if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
                if (NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e')
 
                {
                                state = CORE_S2;
                                state = CORE_S2;
                                transition_count[CORE_FLOAT]++;
                                transition_count[CORE_FLOAT]++;
                        }
                        }
                        else if(!ee_isdigit(NEXT_SYMBOL)) {
                else if (!ee_isdigit(NEXT_SYMBOL))
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_FLOAT]++;
                                transition_count[CORE_FLOAT]++;
                        }
                        }
                        break;
                        break;
                case CORE_S2:
                case CORE_S2:
                        if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
                if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-')
 
                {
                                state = CORE_EXPONENT;
                                state = CORE_EXPONENT;
                                transition_count[CORE_S2]++;
                                transition_count[CORE_S2]++;
                        }
                        }
                        else {
                else
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_S2]++;
                                transition_count[CORE_S2]++;
                        }
                        }
                        break;
                        break;
                case CORE_EXPONENT:
                case CORE_EXPONENT:
                        if(ee_isdigit(NEXT_SYMBOL)) {
                if (ee_isdigit(NEXT_SYMBOL))
 
                {
                                state = CORE_SCIENTIFIC;
                                state = CORE_SCIENTIFIC;
                                transition_count[CORE_EXPONENT]++;
                                transition_count[CORE_EXPONENT]++;
                        }
                        }
                        else {
                else
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_EXPONENT]++;
                                transition_count[CORE_EXPONENT]++;
                        }
                        }
                        break;
                        break;
                case CORE_SCIENTIFIC:
                case CORE_SCIENTIFIC:
                        if(!ee_isdigit(NEXT_SYMBOL)) {
                if (!ee_isdigit(NEXT_SYMBOL))
 
                {
                                state = CORE_INVALID;
                                state = CORE_INVALID;
                                transition_count[CORE_INVALID]++;
                                transition_count[CORE_INVALID]++;
                        }
                        }
                        break;
                        break;
                default:
                default:

powered by: WebSVN 2.1.0

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