SystemC came about because of the need to model systems-on-a-chip (SoCs). SoCs require concurrent modeling of hardware and software, increasing complexity to a level that could not be managed any other way. Today’s use of SystemC ranges from SoC design to FPGA design to test and verification of chips.
However, if we look a little deeper, it becomes clear that SystemC has much more to offer in a variety of different technology domains and applications. The platform is actually well-suited to model almost any real-life system or organism. It offers an extensible framework, an integral concept of time at multiple scales, the ability to encapsulate algorithms and behavior in modules with well-defined interfaces, the ability to model concurrent behavior, hardware agnosticism, and the ability to provide a variety of visualization mechanisms.
SystemC is essentially a C++ library that extends the C++ language by adding a timed model and hardware semantics to accurately model the hardware. Interestingly, it separates modules encapsulating behavior from that of the communication mechanisms between them. That characteristic coupled with the ability to encapsulate and develop a hierarchical implementation makes it possible to start the model with a very simple element and communication model. Encapsulation also hides the complexity from one scale to the next. The well-defined interface exposed by the encapsulated entity can be made as sophisticated as needed to expose the inherent behavior without exposing the implementation complexity.
This building-block approach mimics how nature achieves its ultimate complexity. When one scrutinizes an organism, it starts to reveal its details and the interaction of its different parts. The parts and the interactions are labeled at that scale. Upon further magnification, the part reveals a whole different set of entities and their interactions. This top-down approach hasn’t been widely explored in SystemC. Most current SystemC applications aim at chip synthesis and testing, usually more bottom-up uses of SystemC.
This article looks at a more holistic approach to using SystemC for modeling. It also attempts to expose the latent strengths of the SystemC framework that could be exploited in modeling systems.
Modeling Abstraction Hierarchy
SystemC allows a natural method of conceptualizing a system. Initially, the concepts can be captured in high-level blocks or “modules” with simple communication signals or “channels” connecting them. Modeling time isn’t an issue at this stage. The clock that supplies timing to the modules simply ensures synchronization and concurrency between modules. Modeling at this level can be especially useful in capturing the specification of dynamic behavior, called “executable specification.”
This model is also known as a system architecture model (SAM). It’s unimportant to know how the system is going to be partitioned into hardware and software. A SAM exposes the texture of computation needed in the modules. It shows the complexity and nature of computations involved, as well as the memory-access patterns, floating-point intensive operations, external event interactions, and distributable data patterns. On the communications side, it establishes the interfaces between the modules. As a result, an architect can play around with redistributing the functionality between modules, or create new modules to make the interfaces more efficient.
The interfaces establish the complexity of communications. As they get refined, the modules form the natural boundaries for selecting the implementation architecture. Figure 1 highlights SystemC’s ability to support the different phases of the design cycle.
Modeling Time
SystemC’s simulator has the flexibility to create any number of clocks with widely varying timing. One can exploit this flexibility to have events happening at long intervals interspersed with events that happen very rapidly. The fastest events generated are in the order of picoseconds. Figure 2 visually describes the modules running at different time scales and starting at varying times.
Initial designs can start with just a clock for creating synchronization among modules and concurrency. With timing refinement, this clock can become the hardware-generated clock, and can be referred to as a timing-accurate model. In addition, there can be a model with pseudo-accurate timing. Such a model is useful in measuring gross timing of modules and their interactions to provide performance estimates of the modeled system. The model can yield first-cut performance estimates and still run at reasonably fast speeds.
Moreover, one can estimate the execution time of the modules on different platforms. This provides an opportunity to explore suitability among different hardware architectures for the modules in the system. Even though this approach isn’t cycle-accurate, it can still offer a degree of sophistication that far surpasses current manual models of estimating performance—due to the communication and interaction model sophistication.