With YAPI we focus on design technology for capturing the functional specifications of signal processing applications. The design technology for capturing the functional specifications of signal processing applications must satisfy a diverse set of requirements. The design technology must provide support for
To meet the above-mentioned requirements we developed YAPI as a C++ library with a set of rules which can be used to model stream processing applications as a process network. The model of computation of YAPI is based on Kahn Process Networks. Such a network consists of concurrent processes that communicate via unbounded fifos. In Kahn Process Networks (KPN) parallelism and communication are explicitly modeled, which is essential for the mapping onto multi-processor systems. Another property of KPN is that an application designer can combine processes into networks without specifying their order of execution. This property stimulates the modular construction and reuse of applications (functional IP), since it is easy to compose new applications using existing ones.
An example process network is shown in Figure 1.3. This process network represents the stream processing functionality of the digital TV set introduced in Section 1.1. A process network consists of concurrent processes that are interconnected by directed first-in-first-out channels which are called fifos. In Figure 1.3 the processes are represented by circles. Each process has a private state space which is not accessible by other processes. The processes have input and output ports through which they communicate with their environment. Each port is connected to precisely one fifo, and each fifo is connected to exactly one output port and exactly one input port. In the figure the ports are represented by black dots, and the fifos are represented by arrows. The structure of a process network, i.e., the binding of fifos to ports, is static; it is known at compile time and does not change at run time. The ports and the fifos are typed which means each instance can handle data of one type only. Different instances can handle different data types.
A process performs a sequence of computation and communication actions that may be arbitrarily interleaved. With YAPI the computations can be specified by any C or C++ construct, whereas the following primitives can be used for communication.
A read action removes data from the fifo and stores it into a local variable of the process, if data is available. If there is no data the read action will block. Depending on the implementation the read may incur context switching with associated state saving. In YAPI, the state saving is implicit since it is invisible to the application designer. The write function copies data from a local variable into the fifo. In theory the fifos are unbounded, so a write action will never block. In practical implementations such as in embedded systems where the amount of memory is limited, the size of a fifo is bounded. Therefore the write action will block if the fifo is full to avoid data loss during communication.
Note that the above-mentioned primitives ensure deterministic behavior, i.e., the same input always results in the same output, and that the size of the fifos determines the set of feasible process schedules. If the fifos are unbounded, then we have maximal process parallelism and we obtain the model of computation known as Kahn Process Networks [16]. If the size of the fifos is zero, then we have minimal process parallelism and we obtain a subset of the model of computation known as Communicating Sequential Processes [17].
In some cases, for instance, in reactive systems where the communication behavior of the environment is unknown, the deterministic communication provided by read and write may be insufficient. To be able to deal with reactive systems we extended the model with non-deterministic communication via the select action. A select action will select one of the ports that will eventually produce or consume the given amount of data. In the example below the select is used to handle the input of a new window width from the window manager.