It wasn’t so very long ago that the high-level synthesis vendors were arguing over the correct language to use. Should it be C, C++, SystemC or some other language, such as M? Their arguments ranged over several issues including which was more abstract, which was faster to write, simulate and debug, which one contained more detail, such as timing, concurrency, structure and many other factors. Thankfully most of the arguments are over because the major vendors now support C, C++ and SystemC equally. Some vendors that weren’t so inclusive have been gobbled up or quietly disappeared. Remarkably new ones seem to be popping up to replace them. The market is big enough for perhaps two of them, not 22! But many of the issues still remain, except in a slightly different form. It really wasn’t a question of which was better, but of which was better for describing certain aspects of a system and which ones were necessary.
In this blog, I would like to consider hierarchy, but which hierarchy? That is where it gets interesting. I remember a long time ago, there was one of the big researchers (sorry I can’t remember which one so that I could give proper credit) that coined the term heterarchy. He used it to describe how several hierarchies could exist at the same time, based on the perspective you were using. Consider this in a very crude way in a software program. We could consider the file hierarchy that is used to contain the source code for a program. This is clearly a hierarchy. Then, some of the files may have includes, so there is a dependence between them, and include files can contain other includes, or definitions. This creates a reference type of hierarchy. But then when we look into the contents of the file we have the call hierarchy. Which routines call other routines and this can of course be recursive. In addition, we could consider the data hierarchy. What are the basic types and enumerated types that are used. How are these combined into structures or unions, and then how are these structures semantically connected together. Each of these forms a hierarchy.
If we extend the program example into the C++ arena, we can add the class hierarchy, but this becomes a lot more complex because of capabilities such as overloading and polymorphism. When we move to SystemC we set up a whole new set of hierarchies based on a different type of decomposition. This can be both a structural and functional decomposition and is used to make code sharing, interface definition and concurrency easier to digest. Code sharing could also be considered to be IP reuse, so this is the way in which external IP blocks are divided and if necessary protected. It also provides some hints as to how the final implementation is to be structured and in an EDA flow, some of this hierarchy can extend way down even into the physical implementation stage.
Structural hierarchy is very important in the hardware flow and it is possible that as software becomes more parallel, this concept may need to migrate over to that side of the fence as well. One of the great things about structural hierarchy is that when we trim a part of the tree, the trimming is complete in that it is a fully functional piece of the entire design. It can be verified independently, synthesized independently (although the interfaces have to be taken into account) and many other operations can be done, then when complete, it can be stitched back into the larger context of the system. This means in part that the functional hierarchy and structural hierarchies overlap each other, but not completely.
Similar to the capabilities in C++, interfaces provide the necessary degree of functional independence between structural entities. The separation of those interfaces can also give you options for verification that otherwise would not exist, such as being able to use those interfaces to directly provide the stimulus desired. In the context of the full design it may be very difficult to do this, or may require very long simulation runs.
The Specman e language added yet another form of hierarchy, that they called Aspect Orientation. While it was not fully developed within the language, it has become a principle that many are looking towards when trying to layer capabilities onto a base model. A good example of this can be found with power modeling. You do not want to modify the original functional model with information about power, you would prefer to see this as an overlay. In that way it is not possible to accidently modify the base description, plus it allows multiple different power versions to be defined from the same functional model. Similar layers could talk about timing.
With all of these hierarchies, you would think that we have plenty of ways to look at a design, and yet we are still missing some important forms of hierarchy, or at least they are not in active usage. The two I would mention are models of computation hierarchies and behavioral hierarchy. What I mean about the first of these is the ability to bring together multiple types of models and have them work together. Famous examples of this are Ptolemy and to a limited extent in things such as Verilog-AMS and VHDL-AMS. There are also some examples of multi-physics simulators used for higher level modeling of electro-mechanical, or electo-optical systems. The second missing hierarchy is behavioral and this one is perhaps more difficult to differentiate compared to what we have today. We can define state machines, which are a piece of functionality, but we have more problems putting together more complex state machines out of simpler ones. Several research programs have operated in this area, but little of it has found its way into tools yet. As we start to have more concurrent, interacting state machines this will become more important over time.
Brian Bailey – keeping you covered