Guaranteeing correct operation of real-time software running on an embedded processor is a significant challenge. Data dependent execution flows, where execution times of many functions are dependent on the data inputs, mean that instruction sequences are very difficult to accurately time.
To handle the problem so far, the test bench has been relied upon to adequately exercise the timing corner cases of each individual function. In complex systems this often means developing much of the rest of the application before suitable stimulus can be created. This adds significant effort and delay to certifying software system timing.
New processor architectures, capable of exhibiting deterministic instruction timing, open up interesting possibilities for the future. A new technique, static timing analysis, based on a deterministic processor architecture, is described in this article and will be shown to be capable of taking the guesswork out of timing in real-time software systems.
In short, a static timing tool will analyse object code and determine worst-case timing paths. Paths are analysed between two points interactively or against timing assertions in batch mode to produce a pass or fail result. This information allows the designer to optimise timing critical sections of their code until correct timing closure is achieved.
The article will show how this approach can be successfully used to develop a software implementation of a 100Mbps Ethernet MII interface.
Closing timing in real-time systems
As processor architectures improve in speed and responsiveness, it becomes increasingly attractive to perform functions traditionally implemented in hardware, using software. A simple example such as an IIC master has always been a good candidate for this approach because the master defines the timing. However, an IIC slave must always be ready to respond within a certain time. This imposes timing constraints on the software. Developing interface functions in software thus becomes a real-time programming challenge.
Verifying software functionality is a well practiced task using software test benches. Closing timing may require a significant amount of additional effort on top of authoring the code. The standard approaches to closing timing are limited. Typical approaches include testing in circuit whilst observing pin activity, simulating the software using a cycle accurate simulator or counting the instructions for the path of interest to determine the expected execution time.
All approaches share a common requirement; that is to provide suitable stimulus to fully exercise the software under test ensuring that corner cases are adequately covered. This increases the verification effort due to extending the test bench to include timing. In many cases, obtaining suitable stimuli may not be possible until much later on in the project when the rest of the system is available to generate it. Static timing analysis removes this dependency by formally exercising all paths within the code and allows timing closure of each software function individually.