The synchronous model of computation divides the program execution into a sequence of logical steps. On the one hand, this view simplifies many analyses and synthesis procedures, but on the other hand, it imposes restrictions on the modeling and optimization of systems. In this article, we introduce refined clocks in imperative synchronous languages to overcome these restrictions while still preserving important properties of the basic model. We first present the idea in detail and motivate various design decisions with respect to the language extension. Then, we sketch all the adaptations needed in the design flow to support refined clocks.
Reviewhave been proposed for the development of safety-critical embedded systems. They are based on a convenient programming model, which allows one to generate deterministic single-threaded code from multi-threaded synchronous programs. Thus, synchronous programs can directly be executed on simple micro-controllers without having the need to use complex operating systems. In addition, synchronous programs can straightforwardly be translated to hardware circuits [4][5][6], which makes synchronous languages attractive for the use in hardware-software co-design. Furthermore, the concise formal semantics of synchronous languages is the basis for formal verification of the correctness of the programs as well as of the used compilers [7][8][9][10]. Finally, since macro steps consist of only finitely many micro steps whose number is known at compile-time, one can determine tight bounds on the reaction time by a simplified worst-case execution time analysis [11][12][13][14].All these advantages are due to the underlying synchronous model of computation [1], which divides the execution of programs into micro and macro steps, where variables change synchronously only between macro steps and remain constant during micro steps. The partitioning into micro and macro steps is explicitly *Correspondence: gemuende@cs.uni-kl.de Department of Computer Science, University of Kaiserslautern, Kaiserslautern, Germany given by the programmer, and the micro steps are executed in a causal ordering so that there are no read-afterwrite conflicts [7,15]. As a consequence, all threads of a program run in lockstep: they execute the micro steps of their current macro steps in the common global variable environment, and therefore automatically synchronize at the end of the macro step.Obviously, the synchronous model of computation enforces deterministic concurrency, which has many advantages in system design, e.g., to avoid Heisenbugs [16] and to allow compile-time analyses, e.g., on WCET. At the same time, however, it imposes tight restrictions on modeling possibilities, since there is no means to express the independence of threads in certain program locations. This phenomenon-where synchronous lockstep execution of threads is enforced even though it is not necessary-is often referred to as over-synchronization. Over-synchronization occurs quite frequently, since the input signals of a system us...