/*! \file sc.c * * Main file for using SyncChart C macros * * See README.txt for general information. * See LICENSE.txt for licensing information. * For further information, see * http://www.informatik.uni-kiel.de/rtsys/sc/ . * * @author Reinhard v. Hanxleden, * rvh@informatik.uni-kiel.de */ #include "sc.h" // =================================================================== //! Computing the id of next thread to be dispatched. /*! Uses obvious algorithm, run time linear in position of highest bit. * Note that there are also alternatives that run logarithmic to bit vector size. * See eg http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog . * Which is actually faster depends on application. */ void selectCid() { int act; _cid = 0; for (act = active; act > 1; act >>= 1) _cid++; } // =================================================================== //! Tracing routines void vec2names(char *prefix, char* suffix, bitvector ids, const char *names[]) { #ifndef _SC_NOTRACE int id = 0; int first = 1; printf("%s", prefix); while (ids) { if (ids & 1) { if (first) { first = 0; } else { printf(", "); } printf("%d/", id); if (names) { printf("%s", names[id]); printVal(id); } else { printf("%s", state[id]); } } ids >>= 1; id++; } if (first) { printf(""); } printf("%s", suffix); #endif } // =================================================================== //! The main program /*! Returns 0 iff outputs generated by program match reference trace */ int main() { int runInstrCnt; // Instructions in one run int runsInstrCnt = 0; // Instructions accumulated over all runs int outputsOK = 1; // Outputs of simulation correct? int notDone; // Automaton still running? signalvector tickInputs; // Input values for a tick signalvector tickOutputs; // Reference output values for a tick signalvector tickSignals; // Reference signal values for a tick // Execute all runs for (runCnt = 0; (runCnt < runMax) && outputsOK; runCnt++) { printf("#### RUN %d STARTS ##################################\n", runCnt); runInstrCnt = 0; tickCnt = 0; enabled = 0; RESET(); // Reset automaton do { // Execute all ticks of one run tickInstrCnt = 0; getInputs(); tickInputs = signals; trace3("==== TICK %d STARTS, inputs = 0%o, enabled = 0%o\n", tickCnt, tickInputs, enabled); vec2names("==== Inputs (id/name): ", "\n", tickInputs, s2signame); vec2names("==== Enabled (id/state): ", "\n", enabled, 0); notDone = tick(); // Call automaton function runInstrCnt += tickInstrCnt; trace2("==== TICK %d terminates after %d instructions.\n", tickCnt, tickInstrCnt); vec2names("==== Enabled (id/state): ", "\n", enabled, 0); vec2names("==== Resulting signals (name/id): ", "", signals, s2signame); outputsOK = checkOutputs(&tickOutputs); if (outputsOK) { tickSignals = tickInputs | tickOutputs; if (signals == tickSignals) { trace0(", Outputs OK.\n\n"); } else { vec2names(", Outputs NOT OK - expected signals ", "!!\n\n", tickSignals, s2signame); outputsOK = 0; } } else { notDone = 0; } tickCnt++; if (tickCnt >= tickMax) { printf("==== Executed tickMax = %d ticks, terminate.\n", tickMax); notDone = 0; } } while (notDone && outputsOK); printf("#### RUN %d terminates after %d instructions\n\n", runCnt, runInstrCnt); runsInstrCnt += runInstrCnt; }; printf("#### All runs terminate, after %d instructions\n\n", runsInstrCnt); return !outputsOK; }