Software Tools for Technology Transfer manuscript No. (will be inserted by the editor)
prialt in Handel-C: an operational semantics Andrew Butterfield ?1 , Jim Woodcock2 1
University of Dublin, e-mail:
[email protected]
2
University of Kent, e-mail:
[email protected]
Received: date / Revised version: date
Abstract. We describe an operational semantics for the hard-
1 Introduction
ware compilation language Handel-C [Cel02], which is a Clike language with channel communication and parallel con-
Handel-C1 [Cel02] is a language originally developed by the
structs which compiles down to mainly synchronously clocked
Hardware Compilation Group at Oxford University Comput-
hardware. The work in this paper builds on previous work de-
ing Laboratory, and now marketed by Celoxica Ltd. It is a
scribing the semantics of the “prialt” construct within Handel-
hybrid of CSP [Hoa85] and C, designed to target hardware
C [BW02] and a denotational semantics for part of the lan-
implementations, specifically field-programmable gate arrays
guage [BW03]. We describe a key subset of the language and
(FPGAs) [PL91]. The language has sequential and parallel
show how a design decision for the real language, namely that
constructs and global variable assignment and channel com-
default guards in prialt-statement executed in “zero-time”,
munication. The language targets synchronous hardware with
has consequences for the complexity of the operational se-
multiple clock domains. All assignments and channel com-
mantics. We present the operational semantics, along with a
munication events take one clock cycle. All expression and
revised and completed prialt semantics, indicating clearly the
conditional evaluations, as well as priority resolutions are deemed
interface between them. We then describe a notion of obser-
to be instantaneous, effectively being completed before the
vational equivalence, and present an example illustrating how
current clock-cycle ends. As the Handel-C language targets hardware, it is ideal for
we handle the complexity of nested prialts in default guards.
implementing embedded systems, often in situations where Key words: Handel-C – operational semantics – priority
high levels of assurance would be desirable [LYL+ ]. There 1
?
Thanks to Dean of Research Fund, TCD.
Handel-C
is
the
(www.celoxica.com)
registered
trademark
of
Celoxica
Ltd
2
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
is a clear need for both a formal semantics of Handel-C (or a
processes is very difficult to treat formally [Fid93,Law01,
reasonable subset) as well as an appropriate methodology and
Law02a, Law02b]. When occam [BGJK88] was developed,
tool support. The research described here is part of a program
the only aspects of the language for which no formal seman-
to provide just such an industrial-strength formal framework.
tics was provided were the constructs which involved priority
This paper describes the current state of work being done
(PRI PAR and PRI ALT). One of the issues is that the asyn-
to provide Handel-C with a formal operational semantics. We
chronous nature of CSP-like formalisms, make it very diffi-
also discuss language features which prove to be problemati-
cult to establish when prialts are “coming together”, in order
cal from an operational semantics perspective.
for their communication requests to be resolved. However, in Handel-C, the presence of a synchronising clock makes it
2 Previous and Related Work
very easy to establish which prialts are active at any given moment, so priority handling amounts to a static problem of
Early work on the formal semantics of Handel-C concen-
resolving priorities of a known collection of prialts.
trated on a subset of the language that did not contain the pri-
In the broader arena of process algebras in general, there
alt construct. This initial exploratory work focussed on mod-
has been considerable work done on priorities [CH88,CLNS96,
elling the flow of control in Handel-C constructs by tracking
CLN01]. In [CLN01] there is an overview of this area, but
how “execution pointers” were created, modified and merged
there is no close match between any of the priority schemes
as parallel threads were forked, executed and terminated. This
described therein, and that which features in the semantics of
led to a formal model of a Handel-C flow-of-control “inter-
Handel-C.
preter” [But01b]. Work then started on exploring a denotational semantics
A formal description of prialt resolution without consideration of default clauses was presented in [BW02]. At this
for the same language subset, which was non-trivial as we
stage, it had become clear that prialt resolution could be treated
had to deal with concurrency, message-passing, shared vari-
orthogonally to most other semantic issues, and so the de-
ables and the synchronous clock. Eventually, results based
notational semantics was reworked slightly to make use of
on branching sequences of functions mapping environments
the prialt semantics [BW03]. In this paper we present a re-
to environments were obtained [But01a].
worked and complete formal semantics for prialt in Appendix
At this point it became clear that prialt would have to
A.
be included. It cannot be simulated using ordinary commu-
Other work involving formal techniques and Handel-C
nication and switch statements, and it has a number of ef-
has been reported. The Ponder policy specification language
fects on the overall semantics. Priority in CSP-like concurrent
has been used as a basis for implementing firewalls in Handel-
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
3
C [LYL+ ]. It uses Handel-C as a suitable implementation
Priority : The communication constructs are provided in the
technology, while the formal aspects seem to be limited to
form of prialt-statements, which requires all choices be-
using Ponder to specify firewall security rules, and to gener-
tween communication events to be prioritised. A com-
ate an optimised intermediate representation. Specifications
plete formalisation of the behaviour of prialts is given in
written in a functional language have been implemented in
Appendix A of this paper.
Handel-C, by using behavioural transformations [Abd03]. A
Asynchronous “environment” : The synchronous cores com-
functional specification can be refined in order to expose par-
municate with each other and the external environment
allelism and improve efficiency, before being converted to
via asynchronous interfaces.
Handel-C code. Here Handel-C macros are used to define implementations of basic building blocks of the functional specification language. None of these papers address the issue of Handel-C’s own semantics.
These four areas can be treated separately to a large degree, as the interfaces between them are simple in character2 . For example, the asynchronous interfaces in Handel-C involve “bus interface” constructs, rather than channels. This means that priority information and related decision-making does
3 Scope of Handel-C Semantics
not cross the boundaries between synchronously clocked regions.
Given that our final aim is a formal semantics of a real language which was itself not formally designed, we are devel-
3.1 Handel-C Abstract Syntax
oping our semantic framework in a manner that allows us to separate concerns as much as possible. In particular, we see the final semantics of Handel-C as having four loosely coupled components:
Note: we frequently use the notation xi as shorthand for x1 , .., xn for appropriate n. In general any term indexed by i, j or k appearing without any clear range indication, should be interpreted as iterating over 1..n in this manner. end of Note.
Types : Handel-C has a range of datatypes, all of which ulThe actual concrete syntax of Handel-C is too unwieldy timately reduce down to specifications of bit strings of for describing the operational semantics, so we shall present fixed length. The underlying type theory is fairly straightan abstract syntax of the Handel-C subset with which we are forward. currently concerned. Synchronous “cores” : These are regions of hardware under First, we assume two given sets of identifiers, one for varithe control of a single clock, and constitutes one of the main areas of concern of this paper. Here we present an operational semantics for the behaviour of these cores.
ables (v, x, y, z ∈ V ar) and the other for channels (c, d ∈ 2
Indeed it could be argued that it is the simplicity of these interfaces that
has contributed to the success of Handel-C.
4
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
Ch). Also provided are expressions built from constants, vari-
The conditional statement (p1 C c B p2 ) evaluates its
ables and various operators and functions (e, s, b ∈ E), as
condition at the beginning of the clock-cycle, and then exe-
found in a typical programming language. The details of the
cutes p1 if c evaluated to true, otherwise it runs p2 .
syntax of such expressions are not of interest in this paper and
The selection (switch, or case) statement (s I [pi ]) eval-
so are not discussed further. We also do not discuss types, but
uates the expression s, which should always result in a value
simply assume that the type system available for channels,
in the range 1..n. The process pi for which i = s then starts
variables and expressions includes both booleans and inte-
executing immediately (i.e in the same clock cycle that s was
gers.
evaluated).
The abstract syntax of a Handel-C program (p ∈ P ) is:
p ∈ P ::= 1 | v := e | p1 C c B p2 | s I [pi ] | b∗p | p1 ; p2 | p1 k p2 | hgi → pi i
Delay Assigment Conditional Selection While Sequential Composition Parallel Composition Prioritised Choice (prialt)
The iteration (or while) statement (b ∗ p) evaluates the boolean expression b. If false, the statement terminates immediately, otherwise the process p starts execution, and b is re-checked once p has terminated. This activity continues until b evaluates to false. The sequential composition (p1 ; p2 ) of two statements simply indicates that the first process runs to completion, and then the second starts up immediately afterward. The semicolon (;) should not be interpreted as marking a “clock tick” — it simply serves to separate the “before” process (p1 ) from
During the life of a Handel-C program, in any given clock cythe “after” process (p2 ). To make this clearer consider the folcle, certain program statements will run, as determined by the lowing program fragment: flow of control — we consider such statements to be active during that cycle, while those statements not running during
b1 ∗ p1 ; b2 ∗ p2 ; p3
the same cycle are deemed inactive. We now give an informal description of the behaviour of each statement, when active. The unit delay (1) statement does nothing, but takes one complete clock cycle to do it.
Consider this fragment starting to execute at the start of a clock-cycle in which both b1 and b2 are false. The first statement terminates immediately, and so the second starts exe-
The assignment statement (v := e) evaluates the expres-
cuting in the same clock cycle. The second statement also
sion e using the current values of any variables it references.
terminates instantly, so control then passes to p3 in the same
The variable v is then updated at the end of the clock cycle.
clock-cycle in which the whole fragment was started.
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
5
Parallel composition (p1 k p2 ) involves both processes
possible guards may become active. The active guard then
starting simultaneously, and it terminates when both processes
engages in its communication action with its complementary
have finished. The two processes execute in true parallel style,
partner in the other prialt, for this clock cycle, and then ac-
in lock-step with the clock.
tivates its continuation process in the next clock cycle. If no
Finally, the prialt (prioritised alternative) statement (hgi →
such active guard exists, then the prialt blocks until the next
pi i) can be viewed as a sequence of guard-process pairs, where
clock cycle, and tries again. If the last guard in the prialt is
the guards (g ∈ G) are either communication actions like
the default, then it will never block, and if no other guard is
input (c?v) or output (c!e) or a default guard (!?) to be in-
deemed active, the default guard becomes active, in which
voked if no communication guard is enabled. The process is
case the guard’s continuation process starts executing imme-
the continuation process of the guard, and runs after the guard
diately. The key point to note here is that the determination
has executed, if the guard becomes active. The default guard
of which possible guards become active is carried out by a
if present must be the last element of the sequence, and we
global analysis of all prialts currently active in the program.
shall denote it by the shorthand !?.
We discuss this aspect of the semantics for prialt in much more detail in section §4 and Appendix A.
g ∈ G ::= c?v | c!e | !?
The process in the guard-process pair may be absent, in which
3.2 Static and Dynamic Restrictions
case we indicate this by 0. 3.2.1 Zero-delay While-Loops The ordering of the guards represents the preferences the prialt has regarding which events actually occur, with earlier
An important static restriction is that the minimum execu-
guards being preferred to later ones. While a prialt is inactive,
tion time of any while-loop body must be one clock-cycle.
all its guards are also inactive, but once a prialt is activated
Certain language constructs have the potential to execute in
its guards initially all enter the requesting state. We define
zero clock cycles: a while-loop takes zero clock cycles if its
two guards as being complementary if they both refer to the
condition is false; a prialt takes zero clock cycles if it has
same channel, but involve different directions (input/output).
an enabled default guard which has no continuation process;
If one of more of the guards in a prialt have matching comple-
and an if-then-else statement can have an empty statement in
mentary requests in other active prialts, then they are deemed
the else-branch. Statements which can execute in zero cycles
to be possible guards. Note that the default guard is always
cause problems with hardware generation (so called “combi-
possible once it becomes requesting. If the global priority
natorial cycles”) and as well with the formal semantics. Vi-
resolution mechanism (see §4) deems it so, then one of the
olations of this restriction are flagged by the compiler which
6
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
then automatically corrects it by putting a delay statement in
our operational semantics can support this aspect of the lan-
parallel with the loop body. For example, the following pro-
guage.
gram, is illegal because the body of the outer loop can execute in zero cycles when b2 is false:
3.2.3 Shared Channels
b1 ∗ (b2 ∗ p) The LRM requires that any given channel (c) during any given This is automatically transformed by the Handel-C compiler clock cycle has exactly one writer (c!e) and exactly one reader into the following: (c?x), and so allows two-way synchronisation only. Experib1 ∗ ((b2 ∗ p) k 1)
mentation with the Handel-C compiler and simulator soon
Now the body of the outer loop takes one clock-cycle, regard-
shows that we can be more liberal here as well. There is no
less of the value of b2 , because the parallel construct only ter-
problem in principle with a channel having many simulta-
minates when both sides do, and the delay (1) takes a whole
neous readers in different processes, and this works fine in
cycle.
Handel-C. A rather more surprising result is that Handel-C actually generates hardware in the case of multiple writers
3.2.2 Shared Variables
during a given clock cycle (it does issue warnings) ! However,
We have a mix of parallel processes and global shared vari-
the behaviour is strange, and differs with different versions of
ables, so Handel-C has a restriction that no variable should
the compilers. We choose to treat this as a (dynamic) error.
ever be assigned by two different processes during one clock cycle. In the language reference manual (LRM) [Cel02] it
3.2.4 Priority Conflict
cites this as a static restriction that forbids distinct parallel threads from assigning to the same variable at any time. How-
It is a serious error for two prialts active in any given clock
ever they then state that programmers may violate this restric-
cycle to have conflicting priority preferences, e.g:
tion, provided they recognise that they have a proof obligation to ensure that interference does not occur. As this, and
hc!99 → .., d?x → ..i || hd!66 → .., c?y → ..i
related semantics, is designed to assist in meeting just such proof obligations, we adopt the more liberal approach — dif-
This leads to combinatorial cycles in the hardware and is un-
ferent processes may write to the same variable on different
recoverable. This is in fact a dynamic restriction, as it is per-
clock cycles. This effectively makes this a dynamic restric-
fectly acceptable for prialts active on different clock cycles to
tion in practice. In sections §5.6.3 and §5.6.4 we show how
have conflicting priorities.
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
4 Overview of prialt Semantics
7
coming active, or runs forever if no such other request ever materialises.
We now present a brief overview of the prialt semantics based
Let us consider two examples, the first straightforward,
on that described in [BW02], but now extended to cover de-
the second involving default clauses in that manner that causes
fault clauses, and interfaced with the operational semantics
most semantic difficulty. The first example has three prialts
described later on in this paper. The complete formal descrip-
executing in parallel:
tion is included here as an appendix (§A). ha!1 → p1 , b!2 → p2 i If a prialt-statement is active during the current clock cyk hc!3 → p3 , d?x → p4 i cle, then its guards are viewed as a prioritised sequence of requests, and if a guard (gi for instance) is deemed to be active,
k he!5 → p5 , b?y → p6 , c?z → p7 i
then it carries out its communication action during the current
We assume that these are the only active prialts present. The
clock cycle. Its continuation process (pi ) then starts execution
overall priorities being expressed here can be summarised as:
at the beginning of the next clock cycle. If no communication
{ a, e } < b < c < d where lesser values denote higher pri-
guard is deemed active, and the prialt has a default guard (!?),
orities. So a and e are preferred to b which is preferred to c,
then the corresponding continuation process (pn ) starts exe-
which itself takes priority over d. Only channels b and c are
cution immediately, i.e. during the current clock cycle. This
possible, as they are the only ones to have both input and out-
immediate execution of a default guard’s continuation pro-
put guards involved in these prialts. As b has higher priority,
cess is a major reason for the complexity of the operational
it will be the channel that is determined to be active by res-
semantics to be presented.
olution. The result is the first and third prialts execute, trans-
In any given clock cycle, there will be zero or more prialts
ferring value 2 across channel b to variable y, and then going
commencing execution. A guard is deemed to be possible if
on to execute p2 and p6 in the next clock cycle. The second
elsewhere there is a complementary guard in some other pri-
prialt remains blocked, waiting on either c or d (preferring c).
alt active during the same clock cycle. The process of deter-
This example also makes very clear the fact that prialts
mining which possible guards, if any, are actually active, is
specify relative priorities, and not absolute ones. If we in-
called Resolution. If a prialt has no active guards after resolu-
terpreted the first prialt as giving a priority 1, and b prior-
tion, and no default guard, then it is blocked, and lies idle for
ity 2, and likewise for the other prialts, then we would find
the rest of the current clock cycle. It then proceeds to resub-
that c has both priority 1 and priority 3, and we might favour
mit its request in the next clock cycle. This either continues
the highest priority (lowest number) so deem c to have a
until some other prialt elsewhere leads to one of its guard be-
higher priority than b. This conflicts with the behaviour of
8
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
the Handel-C simulator, and what is implied by the LRM on this issue.
cess statements are extended as follows: p ∈ P ::= . . .
The second example has two prialts in parallel, with the
|0
second having a default clause which itself is a prialt:
hc!7 → p1 i k hd!0 → p2 , !? : hc?v → p3 ii
Null Process (Skip)
| + hgi i
Communication Request
We allowed the use of 0 in prialts to indicate an empty continuation process, and we now upgrade it to a fully fledged pro-
Initially we have a situation where there are no possible guards, so the first prialt blocks, while the second immediately activates its default clause. This introduces another prialt to the mix, and now channel c becomes possible, and resolution deems it active, to it acts, transferring value 7 across channel c to variable v. It is worth pointing out that the above process is in fact equivalent to hc!7 → p1 i k hd!0 → p2 , c?v → p3 i, but that this simplifying law does not extend to arbitrary continuation processes. This example is used later to illustrate the operational semantics at work.
cess in its own right. It represents a process that does nothing, and takes no time to do it, in contrast with Delay (1) which always takes one full cycle. We could also extend the language further to include delays of two, three or more cycles (2, 3, .., d, d+1, ..). The Communication Request statement (+ hg1 , .., gn i) lodges, in the global environment, a demand to perform one of the guard actions listed, in that order of preference. We also extend the language expression syntax to include two functions on guard-lists: waiting (whgi i) and active (ahgi i), as well as a function on channel identifiers (d(c)) returning
4.1 Breaking prialt down the current value being communicated on that channel. We have captured the notion that a prialt acts in three stages: 1. it submits a request ; 2. it waits until a guard becomes active, otherwise re-submitting
e, s, b ∈ E = normal expression | whgi i | ahgi i | d(c) We will replace all prialts of the form: hgi → pi i by the following equivalent program:
the request on every clock cycle ; +
3. once waiting is over, selects and executes the active guard and process. We shall now introduce some extra constructs to our abstract
hgi i
; whgi i ∗ (1 ;
+
hgi i)
; ahgi i I [act(gi ) ; pi ]
Handel-C syntax, to allow us to represent these three activi-
The first statement lodges the initial request. The second state-
ties more explicitly. The reason for doing this is that prialt’s
ment is a busy-wait loop — as long as the prialt is still wait-
behaviour is too complex to handle “all in one go”. The pro-
ing (whgi i) we wait one clock cycle and resubmit the request.
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
The final statement becomes active on the clock cycle when
9
4.2 Resolution
whgi i becomes false. The expression ahgi i identifies which Resolution is viewed formally as a function (R) which takes guard-process pair is active. We first perform the guard aca set of Prialt requests, and returns a pair called a Resolution, tion (act(g)), and then execute the continuation process. The consisting of an Channel Map and the set of prialts that have function act() translates guards into equivalent processes as remained blocked (no active communication guards). follows: m
R : PP rialt → (Ch → PP rialt) × PP rialt act( ) : G → P m
The notation A → B denotes a finite partial function (map) act(!?) = b 0
from A to B, while PA denotes sets of values drawn from A.
act(c!e) = b 1
The Channel Map maps active channels to the set of requests
act(c?v) = b v := d(c)
invoking that channel which have been deemed active. A Pri-
The default guard does nothing and takes no time, the channel output guard waits one clock cycle, and the channel input guard assigns the data associated with its channel to its variable. The semantics to be presented here ensure that the value of e from the corresponding output guard will have been recorded in the environment, so that d(c) is capable of accessing this value.
alt request is simply modelled as a sequence of guard-process pairs, with an optional process component if a default guard is present. A channel is deemed possible if it occurs in a number of prialts, in both input and output forms. It becomes active if no other possible channels in its own prialts are of higher priority. The formal semantics already published in [BW02] does not deal with default clauses, nor elaborate on how the resolution structure interfaces to the formal semantics of the
If a prialt has a default clause, then no waiting occurs, and rest of the language. This deficiencies are rectified in the verso we get the following simpler translation: sion presented here in Appendix A. hgi → pi , !? → pn+1 i
We shall use the notation < to refer to a typical Resolution pair and refer to its components as γ and B respectively. The
7→ +
hgi , !?i
; ahgi , !?i I [act(gi ) ; pi , pn+1 ]
resolution of our first example would have got the following input: P = { ha!1, b!2i, hc!3, d?xi, he!5, b?y, c?zi }
The only uses of the request and action statements, as well as the wait, active and channel expressions are as a result of translating prialts as just described.
The resulting output would have been: < = ({b 7→ { ha!1, b!2i, he!5, b?y, c?zi }}, { hc!3, d?xi } )
10
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
The function D[[d(c)]] takes a Resolution as argu-
Here the first component: γ = {b 7→ { ha!1, b!2i, he!5, b?y, c?zi }}
ment and returns the expression being outputted onto channel c. It is only defined if channel c is in the do-
captures the fact that channel b is active, and indicates the two prialts within which it is active. The second component:
main of the channel map part of the Resolution, i.e. is active.
B = { hc!3, d?xi } 5 Operational Semantics
indicates the remaining blocked prialt. The rest of the interfacing is handled by three partial observer functions: W, A and D. These are represented in the (extended) syntax of Handel-C by the expressions whgi i, ahgi i
The operational semantics for Handel-C requires us to have an understanding of the processing that takes place during a clock-cycle. First, the atomic actions (assignment or commu-
and d(c), respectively, and these functions are only defined nication) for the current clock cycle need to be determined. over these corresponding expression forms. Two of the funcThis involves following the flow of control from the statetions are also partial even when applied to an expression of ments which executed on the previous clock cycle, requiring the appropriate form, as mentioned below. We indicate a parp
tial function between A and B by A → B.
the evaluation of conditional and while-loop guard expressions. We shall refer to this as the “select” (sel ) phase. At
Wait:
this point we have identified almost all of the assignments p
W : E → Resltn → B
and prialts which are about to execute.
The function W[[whgi i]] takes a Resolution as argu-
The next phase, the “request” phase (req) involves all the
ment and returns a boolean result which is T RUE if
selected prialts lodging their corresponding requests with the
the corresponding request (hgi i) is blocked.
environment. At the end of this phase, the system has global
Active:
knowledge of almost all the communication requests associp
p
A : E → Resltn → N
ated with this clock cycle.
The function A[[ahgi i]] takes a Resolution as argu-
The third, or “resolve” phase (res), is where the system
ment and returns a integer result which indicates the
resolves all these requests, as described in section 4 previ-
index of the guard in hgi i which is active. It is only
ously. The outcome of this is that we now know which com-
defined if W[[whgi i]] returns FALSE.
munication actions are going to be executed. The final or “action” phase (act) is where all the atomic
Data: p
p
D : E → Resltn → E
assignment and active communication actions take place, all
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
11
globally synchronised to the clock. It is at this stage that per-
bitrary but finite depth in this fashion (via default guards).
manent changes are made to the system state — i.e. ones that
Given a prialt nesting depth of d, in general we need to it-
persist across clock boundaries.
erate the first three phases d + 1 times. This complication is
The first three phases are all implemented as combinato-
a consequence of the decision that default guards take zero-
rial logic, and are deemed to execute in “zero-time”. In other
time. The presence of arbitrary Handel-C processes as con-
words, this logic makes these decisions well within the time
tinuations after communication guards (non-default) is not a
allocated to the clock cycle. The last phase is effectively syn-
problem, as they don’t start execution until the subsequent
chronised to the end of the cycle, and so is deemed to have
clock cycle.
taken one clock cycle to execute. So, our operational semantics needs to model these four The sequencing of the phases is very important, as the phases by outcome of resolution is not well-defined until the selection and request phases are complete. As resolution determines the final communication actions and their consequent permanent state changes, is important to get this sequencing right.
1. classifying statements according to the phase in which they participate
In the hardware implementation, this is achieved by letting
2. providing transitions of different types for each phase
the resulting combinatorial logic have enough time to settle
3. providing special transitions to manage the switch be-
into a consistent state, and aided by the fact that the logic
tween phases.
contains no “combinatorial” cycles. In our formal semantics we ensure the appropriate ordering of decisions by modelling these conceptual phases explicitly. 5.1 Transition Types We now explain the frequent use in the previous few paragraphs of the phrase “almost all”. The problem here is the existence of default clauses in prialts, which execute in “zerotime”. As a consequence of this, the corresponding continua-
A Transition type (TType) is one of state-selection (sel ),
tion process starts execution in the current clock cycle. This
comms-request (req), comms-resolution (res) or state update
continuation process can be any legal Handel-C process so
action (act), ordered as just listed.
may contain conditionals, parallel branches, while-loops and more prialts. This means that we have to redo the select, request and resolve phases. The prialts can be nested to an ar-
TType = b { sel , req, res, act }
sel < req < res < act
12
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
The system state is larger than just p and t, comprising a
We classify statements by associating a transition type set (tts(p)) with them, and use ttype(p) to denote min(tts(p)):
tuple (p, t, ρ, γ, B, τ ) : Stat
tts : P → PTType where: tts(0) = b { sel } p:P
is the process syntax-state;
t : TType
is the current transition type;
tts(p1 C c B p2 ) = b { sel } tts(s I [pi ]) = b { sel }
m
ρ : Id → Val
tts(b ∗ p) = b { sel }
m
tts(hgi → pi i) = b { req } tts(+ hgi i) = b { req } tts(ahgi i I [pi ]) = b { res }
is the variable environment;
γ : Ch → G+
are the active channels;
B : P(G+ )
are the requested/blocked prialts;
τ :N
is the current clock value.
Note that B holds the resolution input data during the req
tts(whgi i ∗ p) = b { res },
w = FALSE
phase, and (γ, B) holds the resolution result obtained during
tts(whgi i ∗ p) = b { act },
w = T RUE
the res phase. We will frequently use < to refer to this pair of
tts(1) = b { act }
state components. Given an initial program p0 , the initial system state is
tts(v := e) = b { act }
(p0 , sel , θ, θ, ∅, 0)
tts(p1 ; p2 ) = b tts(p1 ) tts(p1 k p2 ) = b tts(p1 ) ∪ tts(p2 ) ttype : P → TType ttype(p) = b min(tts(p))
where θ denotes an empty map, and ∅ an empty set. A program has terminated if it ever reduces to 0. To get the terminating clock transition we shall strengthen this to say that a program terminates once p is 0 and t is sel 3 .
The anomalous situation regarding the classification of whgi i∗ p is explained when the transition rules are described. It is
5.2 Transition Events
also worth nothing that the above classification depends imWe associate events with some transitions, denoting a tranplicitly on the system state in order for w to be evaluated. This
t
sition of type t engaging in event e by −→ , except for the e
system state will be introduced shortly. In addition to the four special transitions were the event is fixed. All events describe transition types mentioned above, we have special transitions some form of system state change, in addition to that already between those types: sel 2req, req2res, res2sel , res2act, and act2sel (a.k.a tick ).
3
It is worth pointing out that the Handel-C compiler requires any program
for hardware is to be generated to be non-terminating.
Andrew Butterfield, Jim Woodcock: prialt in Handel-C: an operational semantics
13
Formally we can view all events as functions on global transition event notation req act
+
changes
hgi i
B ∪ { hgi i }
x := k
ρ † {x 7→ k}
state: Evt = b State → State
req2res
< := Resolve(