Formal Verification of Probabilistic SystemC Models with Statistical Model Checking

12/04/2017 ∙ by Van Chan Ngo, et al. ∙ Carnegie Mellon University 0

Transaction-level modeling with SystemC has been very successful in describing the behavior of embedded systems by providing high-level executable models, in which many of them have inherent probabilistic behaviors, e.g., random data and unreliable components. It thus is crucial to have both quantitative and qualitative analysis of the probabilities of system properties. Such analysis can be conducted by constructing a formal model of the system under verification and using Probabilistic Model Checking (PMC). However, this method is infeasible for large systems, due to the state space explosion. In this article, we demonstrate the successful use of Statistical Model Checking (SMC) to carry out such analysis directly from large SystemC models and allow designers to express a wide range of useful properties. The first contribution of this work is a framework to verify properties expressed in Bounded Linear Temporal Logic (BLTL) for SystemC models with both timed and probabilistic characteristics. Second, the framework allows users to expose a rich set of user-code primitives as atomic propositions in BLTL. Moreover, users can define their own fine-grained time resolution rather than the boundary of clock cycles in the SystemC simulation. The third contribution is an implementation of a statistical model checker. It contains an automatic monitor generation for producing execution traces of the model-under-verification (MUV), the mechanism for automatically instrumenting the MUV, and the interaction with statistical model checking algorithms.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 19

page 20

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

Transaction-level modeling (TLM) with SystemC has become increasingly prominent in describing the behavior of embedded systems [7], e.g., System-on-Chips (SoCs). Complex electronic components and software control units can be combined into a single model, enabling simulation of the whole system at once. In many cases, models have probabilistic and non-deterministic characteristics, e.g, random data and reliability of the system’s components. Hence, it is crucial to evaluate the quantitative and qualitative analysis of the probabilities of system properties.

1.1 Motivation

We consider a safety-critical system, e.g., a control system for an air-traffic, automotive, or medical device. The reliability and availability of the system can be modeled as a stochastic process, in which it exhibits both timed and probabilistic characteristics. For instance, the reliability and availability model of an embedded control system [21]

that contains an input processor connected to groups of sensors, an output processor connected to groups of actuators, and a main processor that communicates with the I/O processors through a bus. Suppose that the sensors, actuators, and processors can fail and the I/O processors have transient and permanent faults. When a transient fault occurs in a processor, rebooting the processor repairs the fault. The times to failure and the delay of reboot are exponentially distributed. Thus, the reliability of the system can be modeled by a

Continuous-Time Markov Chain

(CTMC) [40, 12] (a special case of a discrete-state stochastic process

in which the probability distribution of the next state depends only on the current state). The analysis can be quantifying the probabilities or rates of all safety-related faults: How likely is it that the system is available to meet a demand for service? What is the probability that the system repairs after a failure (e.g., the system conforms to the existent and prominent standards such as the

Safety Integrity Levels (SILs))?

In order to conduct such analysis, a general approach is modeling and analyzing a probabilistic model of the system (e.g., Markov chains, stochastic processes), in which the algorithm for computing the measures in properties depends on the class of systems being considered and the logic used for specifying the property. Many algorithms with the corresponding mature tools are based on model checking techniques that compute the probability by a numerical approach [5, 8, 34, 16]. Timed automata with mature verification tools such as UPPAAL [22]

are used to verify real-time systems. For a variety of probabilistic systems, the most popular modeling formalism is Markov chain or Markov decision processes, for which

Probabilistic Model Checking (PMC) tools such as PRISM [17] and MRMC [20] can be used. PMC is widely used and has been successfully applied to the verification of a range of timed and probabilistic systems. One of the main challenges is the complexity of the algorithms in terms of execution time and memory space due to the size of the state space that tends to grow exponentially, also known as the state space explosion. As a result, the analysis is infeasible. In addition, these tools cannot work directly with the SystemC source code, meaning that a formal model of SystemC model needs to be provided.

An alternative way to evaluate these systems is Statistical Model Checking (SMC), a simulation-based approach. Simulation-based approaches produce an approximation of the value to be evaluated, based on a finite set of system’s executions. Clearly, compared to the numerical approaches, a simulation-based solution does not provide an exact answer. However, users can tune the statistical parameters such as the absolute error and the level of confidence, according to the requirements. Simulation-based approaches do not construct all the reachable states of the model-under-verification (MUV), thus they require far less execution time and memory space than the numerical approaches. For some real-life systems, they are the only option [43] and have shown the advantages over other methods such as PMC [16, 19].

1.2 Contribution

In this article, we demonstrate the successful use of SMC to carry out directly qualitative and quantitative analysis for probabilistic temporal properties of large SystemC models. SMC also allows designers to express a wide range of useful properties. The work makes the following contributions.

  • We propose a framework to verify bounded temporal properties for SystemC models with both timed and probabilistic characteristics. The framework contains two main components: a monitor observing a set of execution traces of the MUV and a statistical model checker implementing a set of hypothesis testing algorithms. We use techniques proposed by Tabakov et al. [37] to automatically generate the monitor. The statistical model checker is implemented as a plugin of the checker Plasma Lab [3], in which the properties to be verified are expressed in Bounded Linear Temporal Logic (BLTL).

  • We present a method that allows users to expose a rich set of user-code primitives in form of atomic propositions in BLTL. These propositions help users exposing the state of the SystemC simulation kernel and the full state of the SystemC source code model. In addition, users can define their own fine-grained time resolution that is used to reason about the semantics of the logic expressing the properties rather than the boundary of clock cycles in the SystemC simulation.

  • We implement a tool, in which the properties of interest are expressed using BLTL. The various features of the tool including automatic generation of monitor for generating execution traces of the MUV, mechanism to instrument automatically the MUV, and the interaction with statistical model checking algorithms are presented. We demonstrate our approach through a running example, as well as the performance of the framework through some experiments.

  • To make our verification perform on all possible execution orders of the MUV, we implement a probabilistic scheduler. Specifically, the source of process scheduling is the evaluation phase in the current SystemC scheduler implementation, in which one of the runnable processes is executed. Every time at the evaluation phase, given a set of runnable processes, our probabilistic scheduler randomly chooses one of these processes to execute. The random algorithm is implemented by generating a random integer number uniformly over the range .

2 Background

This section introduces the SystemC modeling language and reviews the main features of statistical model checking for stochastic processes as well as bounded linear temporal logic which is used to express system properties.

2.1 SystemC Language

2.1.1 Language Features

SystemC111IEEE Standard 1666-2005 is a C++ library [13] providing primitives for modeling hardware and software systems at the level of transactions. Every SystemC model can be compiled with a standard C++ compiler to produce an executable program called executable specification. This specification is used to simulate the system behavior with the provided event-driven simulator. A SystemC model is a hierarchical composition of modules (). Modules are building blocks of SystemC design, they are like modules in Verilog [39], classes in C++. A module consists of an interface for communicating with other modules and a set of processes running concurrently to describe the functionality of the module. An interface contains ports () that are similar to the hardware pins. Modules are interconnected using either primitive channels (e.g., the signals, ) or hierarchical channels via their ports. Channels are data containers that generate events in the simulation kernel whenever the contained data changes.

Processes are not hierarchical, so no process can call another process directly. A process is either a thread or a method. A thread process () can suspend its execution by calling the library statement or any of its variants. When the execution is resumed, it will continue from that point. Threads run only once during the execution of the program and are not expected to terminate. On the other hand, a method process () cannot suspend its execution by calling and is expected to terminate. Thus, it only returns the control to the kernel when reaching the end of its body.

An event is an instance of the SystemC event class () whose occurrence triggers or resumes the execution of a process. All processes which are suspended by waiting for an event are resumed when this event occurs, we say that the event is notified. A module’s process can be sensitive to a list of events. For example, a process may suspend itself and wait for a value change of a specific signal. Then, only this event occurrence can resume the execution of the process. In general, a process can wait for an event, a combination of events, or for an amount of time to be resumed.

In SystemC, integer values are used as discrete time model. The smallest quantum of time that can be represented is called time resolution, meaning that any time value smaller than the time resolution will be rounded off. The available time resolutions are , , , , , and . SystemC provides functions to set time resolution and declare a time object.

The example in Fig. 1 describes a simple delay flip-flop, in which and are predefined primitive input and output ports. The sensitivity list contains the edge sensitivity specified on , which indicates that only on the rising edge of does get transferred to . The sensitivity list and process instantiation are defined in the class constructor ().

Figure 1: An Implementation of Flip-Flop in SystemC.

2.1.2 Simulation Kernel

The SystemC simulator is an event-driven simulation [1, 28]. It establishes a hierarchical network of finite number of parallel communicating processes which are under the supervision of the distinguished simulation kernel process. Only one process is dispatched by the scheduler to run at a time point, and the scheduler is non-preemptive, that is, the running process returns control to the kernel only when it finishes executing or explicitly suspends itself by calling . Like hardware modeling languages, the SystemC scheduler supports the notion of delta-cycles [24]. A delta-cycle lasts for an infinitesimal amount of time and is used to impose a partial order of simultaneous actions which interprets zero-delay semantics. Thus, the simulation time is not advanced when the scheduler processes a delta-cycle. During a delta-cycle, the scheduler executes actions in two phases: the evaluate and the update phases. The semantics of the scheduler is given in Fig. 2. Each phase of the scheduler is explained as follows.

Figure 2: Semantics of SystemC kernel.
  • Initialize. During the initialization, each process is executed once unless it is turned off by calling , or until a synchronization point (e.g., a ) is reached. The order in which these processes are executed is unspecified.

  • Evaluate. The kernel starts a delta-cycle and runs all processes that are ready to run one at a time. In this same phase a process can be made ready to run by an event notification.

  • Update. Execute any pending calls to resulting from calls to in the evaluate phase. Note that a primitive channel uses to have the kernel call its function after the execution of processes.

  • Delta-cycle Notification. The kernel enters the delta notification phase where notified events trigger their dependent processes. Note that immediate notifications may make new processes runnable during step (2). If so the kernel loops back to step (2) and starts another evaluation phase and a new delta-cycle. It does not advance simulation time.

  • Simulation-cycle Notification. If there are no more runnable processes, the kernel advances simulation time to the earliest pending timed notification. All processes sensitive to this event are triggered and the kernel loops back to step (2) and starts a new delta-cycle. This process is finished when all processes have terminated or the specified simulation time is passed.

2.2 Bounded Linear Temporal Logic

We here recall the syntax and semantics of BLTL [35], an extension of Linear Temporal Logic (LTL) with time bounds on temporal operators. A formula is defined over a set of atomic propositions which can be either or . A BLTL formula is defined by the following BNF grammar, in which and are Boolean constants. The time bound is an amount of time or a number of states in an execution trace.

The temporal modalities (the “eventually”, sometimes in the future) and (the “always”, from now on forever) can be derived from the “until” as follows.

The semantics of BLTL is defined with respect to execution traces of a model . Let , where , be a sequence of pairs of states and time points, where the model stays in the state for duration of time. The sequence is called an execution trace of . We use and to denote the prefix and suffix of respectively. We denote the fact that satisfies the BLTL formula by . The semantics is given as follows.

  • and

  • iff , where is the set of atomic propositions which are in state

  • iff and

  • iff

  • iff there exists such that , , and for each

Here is a simple temporal property expressed in BLTL that can be verified with SMC:

The meaning of is: What is the probability that during the time units of the system operation, if holds then, starting from time units after, happens before within time units?

2.3 Statistical Model Checking

Let be the formal model of the MUV (e.g., a stochastic process, a CTMC) and be a property expressed as a BLTL formula. BLTL ensures that the satisfaction of a formula is decidable in a finite number of steps. The statistical model checking [23] problem consists in answering the following questions:

  • Qualitative Analysis. Is the probability that satisfies greater or equal to a threshold with a specific level of statistical confidence?

  • Quantitative Analysis. What is the probability that satisfies with a specific level of statistical confidence?

They are denoted by and , respectively. Many statistical model checkers have been implemented [3, 42, 16, 19] that have shown their advantages over other methods such as PMC on several case studies.

The key idea is to associate each execution trace of with a discrete random Bernoulli variable . The outcome for , denoted by , is if the trace satisfies and otherwise. The predominant statistical method for verifying is based on hypothesis testing. Let , to determine whether , we test the hypothesis against the alternative hypothesis based on the observations of . The size of indifference region is defined by . If we take acceptance of to mean acceptance of as true and acceptance of to mean rejection of as false, then we can use acceptance sampling (e.g., Younes in [41] has proposed two solutions, called single sampling plan and sequential probability ratio test) to verify . An acceptance sampling test with strength , where , guarantees that is accepted with probability at most when holds and is accepted with probability at most when

holds, called a Type-I error (

false negative

) and Type-II error (

false positive), respectively. The probability of accepting is therefore at least . We say that is the confidence of the hypothesis testing.

To answer the quantitative question, , an alternative statistical method, based on estimation

instead of hypothesis testing, has been developed. For instance, the probability estimations are based on results derived by Chernoff and Hoeffding bounds 

[18]. This approach uses observations to compute an approximation of : . If we require that the probability that difference between the approximation and the actual value is bounded by is at least , where , or . Then, based on the theorem of Hoeffding, the number of observations which is determined from the absolute error and the confidence is .

Although SMC can only provide approximate results with a user-specified level of statistical confidence, it is compensated for by its better scalability and resource consumption. Since the models to be analyzed are often approximately known, an approximate result in the analysis of desired properties within specific bounds is quite acceptable. SMC has recently been applied in a wide range of research areas including software engineering [16] (e.g., verification of critical embedded systems), system biology, or medical area [19].

3 A Running Example

We will use a simple case study with a First-In First-Out (FIFO) channel as a running example (see Fig. 3 with the graphical notations in [13]). This example illustrates how designers can create hierarchical channels that encapsulate both design structure and communication protocols. In the design, once a nanosecond the producer will write one character to the FIFO channel with probability , while the consumer will read one character from the FIFO channel with probability . The FIFO channel which is derived from encapsulates the communication protocol between the producer and the consumer.

Figure 3: Every 1 nanosecond, the producer writes 1 character to the FIFO channel with probability , while the consumer reads 1 character with probability . The FIFO channel is designed to ensure that all data is reliably delivered despite the varying rates of production and consumption

The FIFO channel is designed to ensure that all data is reliably delivered despite the varying rates of production and consumption. The channel uses an event notification handshake protocol for both the input and output. It uses a circular buffer implemented within a static array to store and retrieve the items within the FIFO channel. We assume that the sizes of the messages and the FIFO buffer are fixed. Hence, it is obvious that the time required to transfer completely a message, or message latency, depends on the production and consumption rates, the FIFO buffer size, the message size, and the probabilities of successful writing and reading. The full implementation of the example can be obtained at the website of our tool [33, 31]

, in which the probabilities of writing and reading are implemented with the Bernoulli distributions with probabilities

and respectively from GNU Scientific Library (GSL) [14].

The quantitative analysis under consideration is: What is the probability that each single message is transferred completely (e.g., including the message delimiters) within nanoseconds during nanoseconds of operation? This kind of analysis can, thus, be conducted in the early design steps. To formulate the underlying property more precisely, we have to take into account the agreement protocol between the producer and consumer, e.g., a simple protocol can be every message has special starting delimiter with the character ’&’ and ending delimiter with the character ’@’. Thus, the property can be translated in BLTL as follows:

where is the character read in the FIFO channel by the consumer. The input providing to the SMC checker is . This property is expressed in terms of the characters read in the FIFO channel by the consumer, but the communication protocol between the producer and the consumer is abstracted at a very high level. It is an illustration of a type of property that can be checked on TLM specifications. Consider a concrete implementation of the communication protocol between the producer and the consumer at Register-Transfer Level (RTL), if a property is satisfiable at the transaction level then it is so at the register-transfer level. Therefore, the verification of such a property at the transaction level can be connected to its counterpart at RTL in order to check the correctness of RTL implementations.

4 SMC for SystemC Models

In order to apply SMC for SystemC models which exhibit timed and probabilistic characteristics, this section presents the concepts of state and execution trace for SystemC. It also shows that the operational semantics of this class of SystemC models can be considered as stochastic processes.

4.1 SystemC Model State

Temporal logic formulas are interpreted over execution traces and traditionally a trace has been defined as a sequence of states in the execution of a model. Thus before we can define an execution trace we need a precise definition of the state of a SystemC model simulation. We are inspired by the definition of system state in [37], which consists of the state of the simulation kernel and the state of the SystemC model user-code. We consider the external libraries as black boxes, meaning that their states are not exposed.

Let be the set of simulation kernel phases, be the set of all events, and be the set of all variables in the model that includes all module attributes, ports, and channels. Let be the set of all functions in the model, a configuration of the call stack is represented by a tuple where is the executing function, is its parameters, and is its return values. Let be the set of all call stack configurations. Let be the set of all locations, e.g., a specific statement reached during the execution and is the set of all statuses of all module processes in the model. Then a state is formally represented by a tuple where:

  • is the current phase of the simulation kernel, e.g., delta-cycle notification, simulation-cycle simulation,

  • is the set of events that are notified during the execution of the model,

  • is a map from variables to its domain values,

  • is the current location,

  • is the current configuration of the call stack,

  • is the current status of the module processes, e.g., suspended or runnable.

We consider here some examples about states of the simulation kernel and the SystemC model user-code. Assume that a SystemC model has an event named , then the model state can contain information such as the kernel is at the end of simulation-cycle notification phase and the event is notified.

Consider the running example again, a state can be the information about the characters received by the consumer, represented by the variable with type char, . It also contains the information about the location of the program counter right before and after a call of the function in the module that are represented by two Boolean variables and , respectively. These variables hold the value immediately before and after a call of the function , respectively.

Another example, we consider a module that has statements at different locations in the source code, in which these statements contain the division operator “/” followed by zero or more spaces and the variable “” (e.g., the statement ). Then, a Boolean variable which holds the value right before the execution of all such statements can be used as a part of the states.

Let be the (finite or infinite) set of all states of the model. We use to denote the finite set of variables of primitive type (e.g, usual scalar or enumerated type in C/C++) whose value domain represents the states of a SystemC model.

We have discussed so far the state of a SystemC model execution. It remains to discuss how the semantics of the temporal operators is interpreted over the states in the execution of the model. That means how the states are sampled in order to make the transition from one state to another state. The following definition gives the concept of temporal resolution, in which the states are evaluated only at instances in which the temporal resolution holds. It allows the user to set granularity of time.

Definition 1 (Temporal Resolution).

A temporal resolution is a disjunction of a finite set of Boolean expressions defined over . It specifies when the set of variables is evaluated to generate a new state.

Temporal resolution can be used to define a more fine-grained model of time than a coarse-grained one provided by a cycle-based simulation. We call the expressions in temporal events. Whenever a temporal event is satisfied, or we say that the temporal event occurs, is sampled.

For example, in the producer and consumer model, assume that we want the satisfaction of the underlying BLTL formula to be checked whenever at either the end of simulation-cycle notification or immediately after the event is notified during a run of the model. Hence, we can define a temporal resolution as , where and are Boolean expressions that have the value whenever the kernel phase is at the end of the simulation-cycle notification and the event notified, respectively.

We denote the set of occurrences of temporal events from along an execution of a SystemC model by , called a temporal resolution set. The value of a variable at an event occurrence is defined by a mapping , where is the value domain of .

A mapping is called a time event that identifies the simulation time at each occurrence of an event from the temporal resolution. Hence, the set of time points, called time tag, which corresponds to a temporal resolution set , is given as follows.

Definition 2 (Time Tag).

Given a temporal resolution set , the time tag corresponding to is a finite or infinite set of non-negative reals , where and .

Therefore, the state of the SystemC model at an event occurrence (with the corresponding simulation time ) is formally defined as follows.

Definition 3 (Model State).

Let be a finite set of variables and be a temporal resolution. Then the state of the model at the simulation time , written , is defined by a tuple .

4.2 Model and Execution Trace

A SystemC model can be viewed as a hierarchical network of parallel communicating processes. Hence, the execution of a SystemC model is an alternation of the control between the model’s processes, the external libraries and the kernel process. The execution of the processes is supervised by the kernel process to concurrently update new values for the signals and variables with respect to the cycle-based simulation. For example, given a set of runnable processes in a simulation-cycle, the kernel chooses one of them to execute first as described in the prior section.

Let be the set of variables whose values represent the states of a SystemC model. The values of variables in are samples of the set of states

. A state can be considered as a random variable following an unknown probability distribution defined from all given probability distributions in the SystemC source code model. Given a temporal resolution

and its corresponding temporal resolution set along an execution of the model , the evaluation of at the event occurrence is defined by the tuple , or a state of the model at , denoted by , where with is the value of the variable at .

We denote the set of all possible evaluations by , called the state space of the random variables in

. State changes are observed only at the moments of event occurrences. Hence, the operational semantics of a SystemC model is represented by a

stochastic process , taking values in and indexed by the parameter , which are event occurrences in the temporal resolution set . An execution trace is a realization of the stochastic process and is given as follows.

Definition 4 (Execution Trace).

An execution trace of a SystemC model corresponding to a temporal resolution set is a sequence of states and event occurrence times, denoted by , such that for each , and .

The value is called the length (finite or infinite) of the execution, also denoted by . Given , the projection of on , written , is an execution trace such that and , , .

4.3 Properties Expressing

Our framework accepts input properties of the forms , , and , where is a BLTL formula. The former is used to compute the probability that is satisfied by the model. The latter asserts that this probability is at least equal to the threshold . The last one returns the mean value of random variable .

The set of atomic propositions in the logic which describes SystemC code features and the simulation semantics is a set of Boolean expressions defined over a subset of called observed variables and the standard operators (). The semantics of the temporal operators in BLTL formulas interpreted over states is defined by a temporal resolution. In other words, the temporal resolution determines how the states are sampled in order to make the transition from one state to another state. The observed variables and temporal resolutions supported by the framework are summarized below; see the tool manual222 http://project.inria.fr/pscv/en/documentation/ for the full syntax and semantics. It should be noted that the current implementation only supports the use of simulation phases, locations, and events to define temporal resolutions. The implementation provides a mechanism that allows users to declare observed variables in order to define the set of propositions via a high-level language in a configuration file as the input of our tool.

  • Attribute. Users can define an observed variable whose value and type are equal to the value and type of a module’s attribute in the user code. Attributes can be public, protected, or private. For example, defines a variable named whose value and type are equal to the value and type of the private attribute of the module instance .

  • Function. Let be a C++ function with arguments in the user code. Users can refer to locations in the source code that contain the function call, immediately after the function call, immediately before the first executable statement, and immediately after the last executable statement in by using Boolean observed variables , , , and , respectively. Moreover, users can define an observed variable , with , whose value and type are equal to the value and type of the return object (with ) or argument of function before executing the first statement in the function body. For example, if the function is defined in the user code, then the formula asserts that the divisor is nonzero whenever the function starts execution.

  • Simulation Phase. There are 18 predefined Boolean observed variables which refer to the 18 kernel states [33]. These variables are usually used to define a temporal resolution. For example, the formula which is accompanied with the temporal resolution requires the value of variable to be zero at the end of every delta-cycle.

  • Event. For each SystemC event , the framework provides a Boolean observed variable that is true only when the simulation kernel actually notifies . For example, the formula which is accompanied with the temporal resolution says that the event is notified at the end of every update phase.

Referring to the running example, the declaration declares a Boolean variable that holds the value immediately before the execution of the model reaches a call site of the function in the module . The characters received by the consumer which is represented by the variable can be declared as , where is a pointer to the object and is an attribute of the module representing the received character. Then the considered property of the running example can be constructed by using the following predicates defined over the variable : and .

Another example, assume that we want to answer the following question: “Over a period of time units, is the probability that the number of elements in the FIFO buffer is between and greater or equal to with the confidence ? The predicates that need to be defined in order to construct the underlying BLTL formula are and , where is an integer variable that represents the current number of elements in the FIFO buffer (it captures the value of the attribute in the module). Then, the property is translated in BLTL with the operator “always” as follows. and the confidence are given as inputs to the checker.

5 Implementation

We have implemented an SMC-based verification tool [30, 31], PSCV, that contains two main original components: a Monitor and Aspect-advice Generator (MAG) and a Statistical Model Checker (SystemC Plugin). The tool whose architecture is depicted in Fig. 4 is considered as a runtime verification tool for probabilistic temporal properties.

5.1 The Architecture

It consists of the following off-the-self, modified and original components.

  • An off-the-self component, AspectC++ [11], a C++ Aspect Oriented Programming (AOP) compiler for instrumenting the MUV.

  • A modified component, a patch SystemC-2.3.0 for facilitating the communication between the kernel and the monitor and implementing a random scheduler.

  • Two original components are MAG, a C++ tool for automatically generating monitor and aspect-advices for instrumentation, and SystemC plugin, a plugin of the statistical model checker Plasma Lab [3].

5.1.1 Execution Trace Extraction

In principle, the full state can be observed during the simulation of the model. In practice, however, users define a set of variables of interest, according to the properties that the users want to verify, and only these variables appear in the states of an execution trace.

Figure 4: PSCV consists of off-the-self components (AspectC++ and Plasma Lab), modified component (patch SystemC-2.3.0), and original components (MAG and SystemC plugin)

Given a SystemC model, we use to denote the set of variables, called observed variables, to expose the states of the SystemC model. Then, the observed execution traces of the model are the projections of the execution traces on , meaning that for every execution trace , the corresponding observed execution trace is . In the following, when we mention execution traces, we mean observed execution traces.

In PSCV, based on the techniques in [37], the set of observed variables and temporal resolution are converted into a C++ monitor class and a set of aspect-advices. MAG generates three files: containing a set of AspectC++ aspect definitions, , and implementing a monitor as a C++ class and another class called that is responsible for invoking the callback functions. The callback functions will invoke the sampling function at the right time point during the MUV simulation.

The monitor has , a sampling function. It waits for a request from the SystemC Plugin. If the request is stopping the current simulation, it then terminates the MUV’s execution. If the plugin requests a new state, then the current values of all observed variables and the simulation time are sent. The function is called at every time point defined by the temporal resolution. These time points can be kernel phases, event notifications, or locations in the MUV code control flow. In such cases, the patch SystemC kernel needs to communicate with the , e.g., when a delta-cycle ends, via a class called to invoke the function of the monitor. In case of locations in the user-code, the advice code generated by MAG will call the callback function to invoke the function.

The aspect in AspectC++ is an extension of the class concept of C++ to collect advice code implementing a common crosscutting concern in a modular way. For example, to access all attributes of a module called and the location immediately before the first executable statement of the function in (defined in the configuration file with the syntax ). MAG will generate the aspect definition in Fig. 5. The full syntax and semantics of aspects can be found at the web-site of AspectC++ [2].

Figure 5: Example of generated AspectC++ aspect.

5.1.2 Statistical Model Checker

The statistical model checker is implemented as a plugin of Plasma Lab [3] that establishes a communication, in which the generated monitor transmits execution traces of the MUV. In the current version, the communication is done via the standard input and output. When a new state is requested, the monitor reports the current state (the values of observed variables and the current simulation time) to the plugin. The length of traces depends on the satisfaction of the formula to be verified, which is finite due to the bounded temporal operators.

Similarly, the required number of traces depends on the statistical algorithms in use (e.g., sequential hypothesis testing or 2-sided Chernoff bound). The full set of algorithms implemented in Plasma Lab can be found at [32].

5.1.3 Random Scheduler

Verification does not only depend on the probabilistic characteristics of the MUV, but it also can be significantly affected by scheduling policy. Consider a simple module consisting of two thread processes as shown in Fig. 6, where is initialized to be .

Figure 6: Example of deterministic execution order.

Assume that we want to compute the probability that is always equal to . Obviously, depends on the execution order of two threads, e.g., its value is if is executed before the execution of and if the order is then .

The current scheduling policy is deterministic, in which it always picks the process that is first added into the queue (the current open-source SystemC kernel implementation uses a queue to store a set of runnable processes). Hence, only one execution order, then , is verified instead of two possible orders. As a result, the computed probability is , however, ideally it should be . Therefore, it is more interesting if a verification is performed on all possible execution orders than a fixed one. In many cases, there is no decision or à priori knowledge of the scheduling to be implemented. Moreover, verification of a specification should be independent of the scheduling policy to be finally implemented.

To make our verification perform on all possible execution orders of the MUV, we have implemented a random scheduler by patching the current open-source SystemC kernel implementation. The source of process scheduling is the evaluation phase, in which one of the runnable processes will be executed. Given a set of runnable processes in the queue every time at the evaluation phase, our random scheduler randomly chooses one of them to execute. The random algorithm is implemented by generating a random integer number uniformly over a range . For more simulation efficiency and implementation simplicity, we employ the function and operator in C/C++.

5.2 The Verification Flow

The verification flow using PSCV consists of three steps, as shown in Fig. 7.

Figure 7: The verification flow consists of 3 steps: writing a configuration file, instrumenting the MUV using AspectC++, and verifying the instrumented MUV using the SystemC plugin

In the first step, users write a configuration file containing a set of typed variables (observed variables), a Boolean expression (temporal resolution), and all properties to be verified. MAG translates the configuration file into a C++ monitor and a set of aspect-advices. The set of aspect-advices is then used by AspectC++ as input to automatically instrument the MUV to expose the user-code’s state and simulation kernel’s state in the second step. The instrumented model and the generated monitor are compiled and linked together with the modified SystemC kernel into an executable model.

Referring to the running example, users can define the set of observed variables , where is the character read in the FIFO buffer and is the number of characters in the FIFO buffer. The temporal resolution will be defined as , where is one of predefined Boolean observed variables which refer to the 18 kernel states [33]. That means that a new state in execution traces is produced whenever the simulation kernel is at the end of simulation-cycle notification phase or every one nanosecond in the example since the time resolution is one nanosecond. The full configuration file is included in the source code of the example333http://project.inria.fr/pscv/producer-and-consumer/.

Finally, SystemC plugin, a plugin of the statistical model checker Plasma Lab [3], simulates independently the executable model in order to make the monitor produce execution traces with inputs provided by users. The inputs can be generated using any standard stimuli-generation technique. These traces are finite in length since the BLTL semantics [35] is defined with respect to finite execution traces. The number of simulations is determined by the statistical algorithm used by the plugin based on the absolute error and the level of confidence. Given these execution traces and the user-defined absolute error and confidence, the SystemC plugin employs the statistical model checking to produce an estimation of the probability that the property is satisfied or an assertion that this probability is at least equal to a threshold.

6 Experimental Results

We report the experimental results for the running example and also demonstrate the use of our verification tool to analyze the dependability of a large embedded control system. The number of components in this system makes numerical approaches such as PMC unfeasible. In both case studies, we used the 2-sided Chernoff bound algorithm with the absolute error and the confidence . The experiments were run on a machine with Intel Core i7 2.67 GHz processor and 4GB RAM under the Linux OS with SystemC 2.3.0, in which the checking of the properties in the running example took from less than one minute to several minutes. The analysis of the embedded and control system case study took almost hours, in which properties were verified.

6.1 Producer and Consumer

Let us go back to the running example in Section 3, recall that we want to compute the probability that the following property satisfies every nanosecond, with the absolute error and the level of confidence . In this verification, both the FIFO buffer size and message size are characters including the starting and ending delimiters, and the production and consumption rates are nanosecond.

First, we compute with various values of and . The results are given in Table 1 with and nanoseconds. Obviously, the probability that the message latency is smaller than time units increases when and increase, where and are probabilities that the producer write to and consumer reads from the FIFO channel successfully. That means in general the latency is shorter when either the probability that the producer successfully writes to the FIFO channel increases, or the probability that the consumer successfully reads increases.

\
Table 1: The probability that the message latency is smaller than in the first nanoseconds of operation

Second, we compute the probability that a message is sent completely (or the message latency) from the producer to the consumer within time units over a period of time units of operation, in which the probabilities and are fixed at . Fig. 8 shows this probability with different values of over nanoseconds. It is observed that the message latency is just below nanoseconds.

Figure 8: The probability that the message latency is smaller than in the first nanoseconds of operation

6.2 Embedded Control System

This case study is closely based on the one presented in [29, 21] but contains many more components. The system consists of an input processor () connected to groups of sensors, an output processor (), connected to groups of actuators, and a main processor (), that communicates with and through a bus. At every cycle of minute, the main processor polls data from the input processor that reads and processes data from the sensor groups. Based on this data, the main processor constructs commands to be passed to the output processor for controlling the actuator groups.

The reliability of the system is affected by the failures of the sensors, actuators, and processors. The probability of bus failure is negligible, hence we do not consider it. The sensors and actuators are used in and modular redundancies, respectively. That means if at least sensor groups are functional (a sensor group is functional if at least of the sensors are functional), the system obtains enough information to function properly. Otherwise, the main processor is reported to shut the system down. In the same way, the system requires at least functional actuator groups to function properly (an actuator group is functional if at least of the actuators is functional). Transient and permanent faults can occur in processors or and prevent the main processor() to read data from or send commands to . In that case, skips the current cycle. If the number of continuously skipped cycles exceeds the limit , the processor shuts the system down. When a transient fault occurs in a processor, rebooting the processor repairs the fault. Lastly, if the main processor fails, the system is automatically shut down. The mean times to failure for the sensors, the actuators, and the processors are 1 month, 2 months and 1 year, respectively. The mean time to transient failure is 1 day and I/O processors take 30 seconds to reboot. In the model we represent 30 seconds as 1 time unit.

The reliability of the system is modeled as a CTMC [26, 40, 12] that is realized in SystemC, in which a sensor group has states (, the number of working sensors), states (, the number of working actuators) for an actuator group, states for the main processor (: failure, : functional), and states for I/O processors (: failure, : transient failure, : functional). A state of the CTMC is represented as a tuple of the component’s states, and the mean times to failure define the delay before which a transition between states is enabled. The delay is sampled from a negative exponential distribution with parameter equal to the corresponding mean time to failure. Hence, the model has about states compared to the model in [21] with about states, that makes the PMC technique unfeasible. That means the state explosion likely occurs, even if some abstraction, e.g., symbolic model checking is applied. The full implementation of the SystemC code and experiments of this case study can be obtained at the website of our tool444https://project.inria.fr/pscv/embedded-control-system/.

We define four types of failures: is the failure of the sensors, is the failure of the actuators, is the failure of the I/O processors and is the failure of the main processor. For example, is defined by . It specifies that the number of working sensor groups has decreased below and the input processor is functional, so that it can report the failure to the main processor. and are observed variables that have same type and value as the number of working sensor groups and the current status of the input processor, respectively. We define , , and in a similar way.

Our analysis is based on the one in [21] with where the properties are checked every time unit. First, we study the probability that each of the four types of failure eventually occurs in the first time units of operation. This is done using the following BLTL formula . Fig. 9 plots these probabilities over the first days of operation. We observe that the probabilities that the sensors and I/O processors eventually fail are more than the probability that the other components do. In the long run, they are almost the same and approximate to , meaning that the sensors and I/O processors will eventually fail with probability . The main processor has the smallest probability to eventually fail.

Figure 9: The probability that each of the 4 failure types is the cause of system shutdown in the first time of operation
Figure 10: The probability that each of the 4 failure types is the cause of system shutdown in the first time of operation

Second, we try to determine which kind of component is more likely to cause the failure of the system, meaning that we determine the probability that a failure related to a given component occurs before any other failures. The atomic proposition indicates that the system has shut down because one of the failures has occurred, and the BLTL formula states that the failure occurs within time units and no other failures have occurred before it. Fig. 10 shows the probability that each kind of failure occurs first over a period of days of operation. It is obvious that the sensors are likelier to cause a system shutdown. At days, it seems that we reached a stationary distribution indicating for each kind of component the probability that it is responsible for the failure of the system.

For the third part of our analysis, we divide the states of system into three classes: “up”, where every component is functional, “danger”, where a failure has occurred but the system has not yet shut down (e.g., the I/O processors have just had a transient failure but they have rebooted in time), and “shutdown”, where the system has shut down [21]. We aim to compute the expected time spent in each class of states by the system over a period of time units. To this end, we add in the model, for each class of state , a random variable that counts the number of times the system is in the state . Hence, it measures the time spent in the class . In our tool, the formula returns the mean value of after time of execution. The results are plotted in Fig. 11. From days, it seems that the amounts of time spent in the “up” and “danger” states are converged at days and days, respectively.

Figure 11: The expected amount of time spent in each of the states: “up”, “danger” and “shutdown”

Finally, we approximate the number of reboots of the I/O processors, and the number of functional sensor groups and actuator groups over time by computing the expected values of random variables that count the number of reboots, functional sensor and actuator groups. The results are plotted in Fig. 12 and Fig. 13. It is obvious that the number of reboots of both processors is double the number of reboots of each processor since they have the same behavior model.

6.3 Random Scheduler

This case study555https://project.inria.fr/pscv/random-scheduler-examples/ consisting of examples evaluates our random scheduler implementation. In example and example , we implement a simple module with thread processes. The processes in the example have no synchronization point using statement, while there is one synchronization point in the example . When these examples are run, we can see that there are execution orders in the first example and there are in total execution orders in the second example.

Example implements a SystemC model containing threads. Each thread has synchronization points using statements with other threads. As a result, each thread has execution segments. Therefore, there are totally execution orders. In the first evaluation, we run the model times with our random scheduler in order to compute its coverage. We got about different execution orders or the scheduler coverage is . Second, we run the model until we get all different execution orders. Then on average we need to run the model times. In other words, the dynamic random verification efficiency of the random scheduler is . It seems that the implementation with the pseudo random number generator (PRNG), by using the function, and operator in C/C++ is not efficient. We are planning to investigate the Mersenne Twister generator [27] that is by far the most widely used general-purpose PRNG in order to better deal with this issue.

Figure 12: Expected number of reboots that occur in the first time of operation
Figure 13: Expected number of functional sensor and actuator groups in the first time of operation

7 Related Work

Some work has been carried out for analyzing stochastic systems with PMC, for example, the dependability analysis of control system with PRISM [21]. PRISM supports construction and analysis of models as Markov chains, determining whether the model satisfies each property expressed in LTL. For example, the exact probabilities can be computed by PRISM. However, the main drawback of this approach is that when it deals with real-world large systems which make the PMC technique is unfeasible, even with some abstraction, i.e., symbolic model checking, is applied.

SMC has been recently applied in a wide range of research areas including software engineering (e.g., verification of critical embedded systems) [16, 36, 44], system biology [19], or medical area [10]. For instance, in [9], a framework of verifying properties of mixed-signal circuits, in which analog and digital quantities interact, was studied. The bounded linear temporal logic is used to express the properties, then the design of circuit and the verifying properties is connected to a statistical model checker. This approach consists of evaluating the properties on a representative subset of behaviors, generated by simulation, and answering the question whether the circuit satisfies the properties with a probability greater than or equal to a threshold.

Several verification techniques have been proposed for SystemC, for example, SystemC Verification Working Group proposed the SystemC Verification Standard (SCV) [1] that provides APIs to verify functionality of programs. However, SCV does not mention temporal specifications. One can use SCV complementary to our verification framework in terms of automatically generating inputs for the MUV.

One of the earliest attempts at checking temporal specification properties for SystemC models is carried out by Braun et al. [4]. The temporal properties are expressed as Finite Linear Temporal Logic (FLTL) and the temporal resolution is defined by the boundary of the simulation-cycle notification. FLTL is linear temporal logic that interprets formulas over finite traces and supports temporal operators with respect to the temporal resolution. Then they proposed two approaches to extend test-bench features to SystemC for checking temporal properties: the checking is implemented directly within the SystemC language as an add-on library as SystemC itself. The other approach is to interface SystemC with an existing external test-bench environment, TestBuilder [6]. As described in [38], the temporal resolution defined at boundary of the simulation-cycle notification is inadequate for SystemC verification, since it does not expose fully the semantics of the SystemC simulator kernel, which gives much finer grained temporal resolution. For example, the simulation may consist of a single delta-cycle if it is driven by immediate event notifications. As a result, the simulation clock never advances.

There has been a lot of work on the formalization of SystemC [15, 25, 47, 46, 45]. In general, the goal of the formalization process is to extract a formal model from a SystemC program, so that tools like model-checkers can be applied. For example, Zeng et al. in [45] translate a subset of the operational semantics of SystemC as a guarded assignment system and use this translated model as an input for symbolic executors and checkers. However, all these formalizations consider semantics of SystemC and its simulator in some form of global model, and they also suffer from the state space explosion when dealing with industrial and large systems.

Tabakov et al. [37, 38] proposed a dynamic-analysis-based framework for monitoring temporal properties of SystemC models. This framework allows users to express the verifying properties by fully exposing the semantics of the simulator as well as the user-code. They extend LTL by providing some extra primitives for stating the atomic propositions and let users define a much finer temporal resolution. Their implementation consists of a modified simulation kernel, and a tool to automatically generate the monitors and aspect-advices for instrumenting SystemC programs automatically with AOP.

8 Conclusion

This article presents the first attempt to verify non-trivial probabilistic and temporal properties of SystemC model with statistical model checking techniques. In comparison with the probabilistic technique, our technique allows us to handle large industrial systems modeling in SystemC as well as to expose a rich set of user-code primitives by automatically instrumenting the user-code with AspectC++. The framework contains two main components: a generator that automatically generates a monitor and instruments the MUV based on the properties to be verified, and a statistical model checker implementing a set of hypothesis testing algorithms. In comparison to the probabilistic model checking, our approach allows users to handle large industrial systems, expose a rich set of user-code primitives in the form of atomic propositions in BLTL, and work directly with SystemC models. For instance, our verification framework is used to analyze the dependability of large industrial computer-based control systems as shown in the case study.

Currently, we consider an external library as a “black box”, meaning that we do not consider the states of external libraries. Thus, arguments passed to a function in an external library cannot be monitored. For future work, we would like to allow users to monitor the states of the external libraries. We also plan to apply statistical model checking to verify temporal properties of SystemC-AMS (Analog/Mixed-Signal).

To improve the dynamic random verification efficiency of the random scheduler’s implementation, we are also planning to use the Mersenne Twister generator [27] that is by far the most widely used general-purpose PRNG instead of the default C/C++ generator.

References

  • [1] Accellera. http://www.accellera.org/downloads/standards/systemc.
  • [2] AspectC++. http://www.aspectc.org/doc/ac-languageref.pdf, 2012.
  • [3] B. Boyer, K. Corre, A. Legay, and S. Sedwards. Plasma Lab: A flexible, distributable statistical model checking library. In QEST’13, pages 160–164, 2013.
  • [4] A. Braun, J. Gerlach, and W. Rosentiel. Checking temporal properties in SystemC specifications. In HLDVT’02, pages 23–27. IEEE International, 2002.
  • [5] D. Bustan, S. Rubin, and M. Vardi. Verifying omega-regular properties of Markov chains. In CAV’04, 2004.
  • [6] Cadence. Design Systems, Inc.: TestBuilder user guide. In Product Version 1.0, 2001.
  • [7] H. Chang, L. Cooke, M. Hunt, G. Martin, A. McNelly, and L. Todd. Surviving the SoC revolution: A guide to platform-based design. In Kluwer Academic Publishers, Norwell, USA, 1999.
  • [8] F. Ciesinski and M. Grober. On probabilistic computation tree logic. In Validation of Stochastic Systems, 2004.
  • [9] E. Clarke, A. Donze, and A. Legay. Statistical model checking of mixed-analog circuits with an application to a third order delta-signam modulator. In HVC’08, 2008.
  • [10] Cmacs. http://cmacs.cs.cmu.edu/.
  • [11] A. Gal, W. Schroder-Preikschat, and O. Spinczyk. AspectC++: Language proposal and prototype implementation. In OOPSLA’01, 2001.
  • [12] A. Goyal and et al. Probabilistic modeling of computer system availability. In Annals of Operations Research, volume 8, pages 285–306, 1987.
  • [13] T. Grotker, S. Liao, G. Martin, and S. Swan. System Design with SystemC. Kluwer Academic Publishers, Norwell, USA, 2002.
  • [14] GSL. http://www.gnu.org/software/gsl/.
  • [15] P. Herber, J. Fellmuth, and S. Glesner. Model checking SystemC designs using timed automata. In CODES/ISSS’08, 2008.
  • [16] H. Hermanns, B. Watcher, and L. Zhang. Probabilistic cegar. In CAV’08. LNCS, Springer, 2008.
  • [17] A. Hinton, M. Kwiatkowska, G. Norman, and D. Parker. PRISM: A tool for automatic verification of probabilistic systems. In TACAS’06. LNCS, Springer, 2006.
  • [18] W. Hoeffding. Probability inequalities for sums of bounded random variables. In American Statistical Association, 1963.
  • [19] S. Jha, E. Clarke, C. Langmead, A. Legay, A. Platzer, and P. Zuliani. A Bayesian approach to model checking biological systems. In CMSB’09. LNCS, Springer, 2009.
  • [20] J. Katoen, E. Hahn, H. Hermanns, D. Jansen, and I. Zapreev. The ins and outs of the probabilistic model checker MRMC. In QEST’09, 2009.
  • [21] M. Kwiatkowska, G. Norman, and D. Parker. Controller dependability analysis by probabilistic model checking. In Control Engineering Practice. Elsevier, 2007.
  • [22] K. Larsen, P. Pettersson, and W. Yi. UPPAAL in a nutshell. Journal on Software Tools for Technology Transfer, 1(1-2):134–152, 1997.
  • [23] A. Legay, B. Delahaye, and S. Bensalem. Statistical model checking: An overview. In RV’10, 2010.
  • [24] R. Lipsett, C. Schaefer, and C. Ussery. VHDL: Hardware description and design. Kluwer Academic Publishers, 1993.
  • [25] F. Maraninchi, M. Moy, C. Helmstetter, J. Cornet, C. Traulsen, and L. Maillet-Contoz. SystemC/TLM semantics for heterogeneous SoCs validation. In NEWCAS/TAISA’08, 2008.
  • [26] M. A. Marsan and M. Gerla. Markov models for multiple bus multiprocessor systems. In IEEE Transactions on Computer, volume 31(3), 1982.
  • [27] M. Matsumoto and T. Nishimura. Mersenne twister: a 623-dimensionally equidistributed uniform pseudo-random number generator. In ACM Transactions on Modeling and Computer Simulation, volume 8(1), pages 3–30, 1998.
  • [28] W. Mueller, J. Ruf, D. Hoffmann, J. Gerlach, T. Kropf, and W. Rosenstiehl. The simulation semantics of SystemC. In DATE 2001, 2001.
  • [29] J. Muppala, G. Ciardo, and K. Trivedi. Stochastic reward nets for reliability prediction. In Communications in Reliability, Maintainability and Serviceability, 1994.
  • [30] V. C. Ngo, A. Legay, and V. Joloboff. PSCV: A runtime verification tool for probabilistic SystemC models. In Computer Aided Verification - 28th International Conference, CAV 2016, Toronto, ON, Canada, July 17-23, 2016, Proceedings, Part I, pages 84–91, 2016.
  • [31] V. C. Ngo, A. Legay, and J. Quilbeuf. Statistical model checking for SystemC models. In HASE’16, 2016.
  • [32] PlasmaLab. https://project.inria.fr/plasma-lab/, 2016.
  • [33] PSCV. https://project.inria.fr/pscv/, 2016.
  • [34] J. Rutten, M. Kwiatkowska, G. Norman, and D. Parker. Mathematical techniques for analyzing concurrent and probabilistic systems. In CRM Monograph Series. American Mathematical Society, Providence, 2004.
  • [35] K. Sen, M. Viswanathan, and G. Agha. On statistical model checking of stochastic systems. In CAV’05, 2004.
  • [36] K. Sen, M. Viswanathan, and G. Agha. Vesta: A statistical model-checker and analyzer for probabilistic systems. In QUEST’05. IEEE Computer Society, 2005.
  • [37] D. Tabakov and M. Vardi. Monitoring temporal SystemC properties. In Formal Methods and Models for Codesign, 2010.
  • [38] D. Tabakov and M. Vardi. Automatic aspectization of SystemC. In MISS’12. ACM, 2012.
  • [39] D. Thomas and P. Moorby. The Verilog hardware description language. In Springer. ISBN 0-3878-4930-0, 2008.
  • [40] K. S. Trivedi. Probability and statistics with reliability, queueing, and computer science applications. In Englewood Cliffs, NJ: Prentice-Hall, 1982.
  • [41] H. Younes. Verification and planning for stochastic processes with asynchronous events. In PhD Thesis, Carnegie Mellon, 2005.
  • [42] H. Younes. Ymer: A statistical model checker. In CAV’05, 2005.
  • [43] H. Younes, M. Kwiatkowska, G. Norman, and D. Parker. Numerical vs statistical probabilistic model checking. In STTT’06, 2006.
  • [44] H. Younes and R. Simmons. Statistical probabilistic model checking with a focus on time-bounded properties. In COMPUT’06, volume 204(9), pages 1368–1409, 2006.
  • [45] N. Zeng and W. Zhang. A systemc semantics in guarded assignment systems and its applications with verds. In Proceedings of the 2013 Asia-Pacific Software Engineering Conference, APSEC ’13, pages 371–379, Washington, DC, USA, 2013. IEEE Computer Society.
  • [46] N. Zeng and W. Zhang. A symbolic partial order method for verifying systemc. In Proceedings of the 2014 21st Asia-Pacific Software Engineering Conference - Volume 01, APSEC ’14, pages 271–278, Washington, DC, USA, 2014. IEEE Computer Society.
  • [47] H. Zhu, J. He, S. Qin, and P. J. Brooke. Denotational semantics and its algebraic derivation for an event-driven system-level language. Formal Aspects of Computing, 27(1):133–166, 2015.