Welcome to Ars-Informatica  


If you want to build a ship don't herd people together to collect wood and don't assign them tasks and work, but rather teach them to long for the endless immensity of the sea. (Antoine-Marie-Roger de Saint-Exupéry)

MetroC: introduction

The key elements of the library are depicted in the picture above along with their relationships:

  • core-lib: a C++ library and simulation kernel that extends C++ using the semantics of the metropolis metamodel;
  • types-lib: an xml based encapsulation mechanism to allow interchange among different domains of data according to well-established interfaces;
  • hw_cosim: a C++ library based on the adapter design pattern that provides the necessary layer that allows two different domains communicate and simulate according to a pre-defined schema. This schema is implemented in the adapter. Since the communication among different domains is an ill problem the implementation has to provide some rules to resolve it.

The core library uses the semantics of the metropolis metamodel. The core of the infrastructure is a meta model of computation, which allows one to model various communication and computation semantics in a uniform way. By defining different communication primitives and different ways of resolving concurrency, the user can, in effect, specify different models of computation (MOCs). At a high level of abstraction, the designer may want to use an MOC that is convenient to describe the functionality.

The functional model just represents what a system is supposed to do. On the other hand, metropolis allows the description of architectures and finally the mapping of the former to the latter. The result of a mapping is another model whose level of abstraction is lower that the original functional model.

The word platform is used to refer to three different kind of platforms:

  • the hardware platform, a family of architectures that satisfy a set of architectural constraints that are imposed to allow the re-use of hardware and software components;
  • the software platform, a layer that wraps the essential parts of the hardware platform in order to allow application software "sees" a high level interface to the hardware (the Application Program Interface or API);
  • the system platform, the combination of hardware and software platform.

In figure the term platform-stack is used to refer to the combination of two platforms (software and hardware) and the tools that map one abstraction into the other. The platform-stack can be seen as a "single" layer obtained by gluing together the top platform and the bottom platform whereby the upper view is the API platform and the lower view is the collection of components that comprise the architecture platform.

When the upper part is mapped on the bottom part, a system platform instance is chosen for that particular stack at a certain level of abstraction. In order to abstract the definition of the hardware platform the use of different models of computation are allowed at different abstraction levels.

The goal of the MetroC core library is to provide the necessary infrastructure to build software and hardware platforms in such a way that each platform stack can be easily explored and connected with other platform stacks.

The key articulation points around which the metropolis framework is built are:

  • the basic components that glued together give birth to the final system (netlists, mediums, processes, ports, etc);
  • a very light, generic and extendible simulation core capable of accommodating different models of computation (MOC). Each MOC may be developed as a library extension on top of the core library. An example of such extension is the xGiotto library.
  • a generic co-simulation framework that allows different platform stacks talk together.

The way the different platform stacks are developed depends on the abstraction level: at top levels C++ code based on Metropolis framework may be more suitable, whereas at the bottom levels VHDL/Prolog models of hardware IP blocks may be used. In order to provide an unified framework that allows different stacks exchange data and use services (API) two libraries have been developed:

  • a co-simulation library that abstract the services by providing a single common API;
  • a library of basic types to handle generic data exchange.

The type library is developed as a set of C++ classes with the same interfaces as C++ basic types. The common operations have been overloaded (plus, minus, etc...) thus using C++ basic types or the corresponding type library classes is exactly the same. The power of the type library classes is exploited during data exchange among different and enterogenous domains where they offer a marshalling mechanism (typeslib) to the co-simulation library.

The methodology is based on defining Platforms at the different key articulation points in the design flow. Each platform represents a layer in the design flow for which the underlying, subsequent design-flow steps are abstracted.

The proposed design flow is shown in figure.

At the top level of abstraction the main functionalities are captured throughout different processes. Once the functionalities are established, these functionalities are tested on a simulation platform (step 1). This platform is purely functional and does not correspond to the target platform. It may have a completely different architecture in terms of cpu, memory, storage, etc. This design process is iterated (step 1-2) until the overall functional model is working.

The design flow of the functional model follows the standard software design cycle. Software life cycle deals with the all activities and work products necessary to develop a software system.

Four fundamental process activities are usually necessary

  • software specification (requirements, functionality and constraints)
  • software development (design and implementation)
  • software validation (ensure that the software meets the customer needs)
  • software evolution (evolve to meet changing customer needs)

The idea of platform based design is to extend software design patterns to hardware platforms moving from left side of the figure to right side of the figure.

Each platform stack can be seen as merging together a chosen software platform instance with a chosen hardware platform instance. According to the level of abstraction step 2 may be realized in the same semantic domain of Metropolis framework or in another domain. Consider for example the task of developing an embedded system, from the low level RTOS up to the applications. The API provided by the OS may be developed in metropolis itself. When the platform stack (step 4,5 and 6) considered is the one that glues together the RTOS and the hardware components of the embedded system it may be more suitable a description in VHDL or verilog of the very same IP blocks.

In order to mingle together different heterogenous subsystems a high level interface along with a predefined set of API to access it have been defined. Each component (either software or hardware) provides a set of services throughout this interface. In the implementation this interface is an unique and generic function called execute().

This execute() is the connecting point between the upper part of the ASV triangle and the lower part. For example, in the Linux OS the execute() function role is carried out by int 0x80.

In a cpu model the call to execute() means fetching from memory one or more instructions, execute them and return the results. At all level of abstraction one can find that this paradigm is true. Since the interfaces are different (int 0x80 in Linux, fetch, decode and execute in a CPU model) according to the type of services offered, the only possibility is to abstract the concept of service. A service is like a black box with inputs and outputs. Once the inputs and outputs are standardized and the internal behavior of the black box is known (the implementor of the black box has captured a feasible behavior to resolve the co-simulation problem) then the user of the black box may just call the execute() function that a feasible execution trace is ensured by construction.

The execute() function role is carried out by the atom in the core-lib. An atom abstracts all the events between the begin and end event of the atom. For instance, an atom cannot contain a request to a quantity because the events in an atom are not visible. An atom is the smallest execution unit that is executed without interruption (by the simulator core) from the begin up to the end. In core-lib compositions of atoms are allowed. One very natural composition is the sequential one that, if things are well architected, will make it possible to map Metamodel processes to MetroC processes. Another one is the parallel composition, that will allow many Metamodel processes to be mapped to one MetroC process.

An atom can be refined in the same core-lib domain or mapped to another domain. Another domain may be an external tool (i.e. an instruction set simulator, a VHDL simulator, etc ...) or another core-lib based block (i.e. a network of nodes developed in Metroc that communicate among them, a discrete domain and a continuous domain, etc ...).