Despite the relative success of this simulation strategy, it still has several shortcomings, especially in the context of large scale simulations. Some of the problems are related to the separation of the circuit representation from the simulation while other problems manifest themselves as a result of the global nature of the event queue. Later sections will describe how replacing the global queue with a series of distributed queues can help to alleviate several of these problems.
A global event queue has no hardware equivalent. In the context of the implementation, the global event queue is an artifact which has no counterpart in an actual circuit. As a result, the implementation must bend the concept of a circuit so as to accommodate this technique for hardware simulation. While this argument may be dismissed as a purely philosophical issue, it does have merit, especially when considering the translation of an abstraction into an implementation. The fewer artifacts an implementation introduces in mimicking the abstraction, the easier it becomes to understand and appreciate the implementation.
Two goals of software engineering and design are to decrease the coupling between unrelated modules while at the same time increasing the cohesiveness within functionally equivalent modules. Many purists may argue that the two tier approach towards digital simulation design serves to decrease the coupling between the simulator and the circuit representation thereby making the software more resilient to change. This assumption, however, is based upon the premise that the circuit representation and its simulation are two disparate entities. However, this separation is purely artificial. Instead, it could legitimately be argued that a design which combines the simulator and the circuit representation increases the cohesiveness of the implementation, since the two concepts are intimately related.
The importance of hierarchical representations of an abstraction was emphasized in Chapter 1 as a means of combating complexity. Hierarchical representation and subsequent simulation of circuits using a global event queue is potentially very convoluted as a result of the pervasive nature of the queue. Because each event in the queue contains a reference to the component to be simulated, it becomes very difficult to represent circuits hierarchically without compromising the autonomy of the low-level subcomponents of a component. One possible workaround to this problem is to place event queues at each level of the hierarchy and to devise a strategy whereby all the queues can be synchronized with one another via a top-level event queue. This may involve changing the concept of an event at the uppermost level of the simulation; instead of containing references to components and signals, events would instead contain references to other event queues. Needless to say, this concept of a global meta-event queue serves to only compound the problem of complexity rather than resolve it.
Related to the hierarchical representation and simulation of the circuit is the potential need to distribute large scale simulations over several different processes or even over several processors. Due to the global nature of the event queue, distribution of such a simulator would be very difficult. This may require the introduction of a process or a machine which is dedicated towards the synchronization of the event queues at each distribution point. Unfortunately, this introduces several problems. For example, if the synchronizing process was running on a separate machine, then that machine would undoubtedly act as a bottleneck during the course of the simulation since every other distribution node partaking in the simulation would have to communicate with it. Worse, if the machine performing the global synchronization went down, the entire simulation would be compromised.
Part of the blame for the proliferation of simulators which rely upon global event queues can be traced back to the languages with which they were implemented. Such languages tend to be structural in nature and provide only primitive support for true data abstraction and no support for inheritance or run-time binding. As a result of the relatively weak encapsulation support, the temptation to introduce global entities into an implementation is very strong. Subsequent sections will demonstrate how circuits may be simulated without the need for a global event queue by encapsulating some of the necessary simulation information within the circuit entities themselves. All the elements required for the simulation map directly onto analogous entities which exist in the real world. Central to the implementation described by this chapter will be the adherence to the principles of good object-oriented analysis and design.