HIGH-LEVEL LANGUAGES AND TOOLS
8.4. Tangram: syntax-directed compilation
Let us now address the synthesis process. The design flow uses an inter- mediate format based on handshake circuits. The front-end design activity is called VLSI programming and, using syntax-directed compilation, a Tan- gram program is mapped into a structure of handshake components. There is a one-to-one correspondence between the Tangram program and the handshake circuit as will be clear from the following examples. The compilation process is thus fully transparent to the designer, who works entirely at the Tangram program level.
The back-end of the design flow involves a library of handshake circuits that the compiler targets as well as some tools for post-synthesis peephole optimization of the handshake circuits (i.e. replacing common structures of handshake components by more efficient equivalent ones). A number of hand- shake circuit libraries exist, allowing implementations using different hand- shake protocols (4-phase dual-rail, 4-phase bundled-data, etc.), and different implementation technologies (CMOS standard cells, FPGAs, etc.). The hand- shake components can be specified and designed: (i) manually, or (ii) using STGs and Petrify as explained in chapter 6, or (iii) using the lower steps in Martin’s transformation-based method that is presented in the next section.
It is beyond the scope of this text to explain the details of the compilation process. We will restrict ourselves to providing a flavour of “syntax-directed compilation” by showing handshake circuits corresponding to the example Tangram programs from the previous section.
8.4.1
The 2-place shift register
As a first example of syntax-directed compilation figure 8.6 shows the hand- shake circuit corresponding to the Tangram program in figure 8.2.
in x ;0 1 2 y out
Figure 8.6. The compiled handshake circuit for the 2-place shift register.
Handshake components are represented by circular symbols, and the chan- nels that connect the components are represented by arcs. The small dots on the component symbols represent ports. An open dot denotes a passive port and a solid dot denotes an active port. The arrowhead represents the direction of the data transfer. A nonput channel does not involve the transfer of data and consequently it has no direction and no arrowhead. As can be seen in figure 8.6 a handshake circuit uses a mix of push and pull channels.
The structure of the program is a forever-do statement whose body consists of three statements that are executed sequentially (because they are separated by semicolons). Each of the three statements is a kind of assignment statement: the value of variableyis “assigned” to output channelout, the value of variable xis assigned to variabley, and the value received on input chanelinis assigned to variablex. The structure of the handshake circuit is exactly the same:
At the top is a repeater that implements the forever-do statement. A repeater waits for a request on its passive input port and then it performs an unbounded repetition of handshakes on its active output channel. The handshake on the input channel never completes.
Below is a 3-way sequencer that implements the semicolons in the pro- gram text. The sequencer waits for a request on its passive input channel, then it performs in sequence a full handshake on each of its active out-
put channels (in the order indicated by the numbers in the symbol) and finally it completes the handshaking on the passive input channel. In this way the sequencer activates in turn the handshake circuit constructs that correspond to the individual statements in the body of the forever-do statement.
The bottom row of handshake components includes two variables,xand y, and three transferers, denoted by ‘’. Note that variables have pas-
sive read and write ports. The transferers implement the three statements
(out!y; y:=x; in?x) that form the body of the forever-do statement,
each a form of assignment. A transferer waits for a request on its passive nonput channel and then initiates a handshake on its pull input channel. The handshake on the pull input channel is relayed to the push output channel. In this way the transferer pulls data from its input channel and pushes it onto its output channel. Finally, it completes the handshaking on the passive nonput channel.
8.4.2
The 2-place FIFO
Figure 8.7 shows the handshake circuit corresponding to the Tangram pro- gram in figure 8.3. The component labeled ‘psv’ in the handshake circuit of figure 8.7 is a so-called passivator. It relates to the internal channelcof the Fifoand implements the synchronization and communication between the ac- tive sender (c!x) and the active receiver (c?y).
in ; 0 1 x psv ; 0 1 y out
Figure 8.7. Compiled handshake circuit for the FIFO program.
An optimization of the handshake circuit forFifo is shown in figure 8.8. The synchronization in the datapath using a passivator has been replaced by a synchronization in the control using a ‘join’ component. One may observe that the datapath of this handshake circuit for the FIFO design is the same as that of the shift register, shown in figure 8.2. The only difference is in the control part of the circuits.
in ; 0 1 x ; 0 1 y out
Figure 8.8. Optimized handshake circuit for the FIFO program.
8.4.3
GCD using guarded repetition
As a more complex example of syntax-directed compilation figure 8.9 shows the handshake circuit compiled from the Tangram program in figure 8.5. Com- pared with the previous handshake circuits, the handshake circuit for the GCD program introduces two new classes of components that are treated in more detail below.
Firstly, the circuit contains a ‘bar’ and a ‘do’ component, both of which are data-dependent control components. Secondly, the handshake circuit contains components that do not directly correspond to language constructs, but rather implement sharing: the multiplexer (denoted by ‘mux’), the demultiplexer (de- noted by ‘dmx’), and the fork component (denoted by ‘’).
Warning: the Tangram fork is identical to the fork in figure 3.3 but the Tan- gram multiplexer and demultiplexer components are different. The Tangram multiplexer is identical to the merge in figure 3.3 and the Tangram demulti- plexer is a kind of “inverse merge.” Its output ports are passive and it requires the handshakes on the two outputs to be mutually exclusive.
The ‘bar’ and the ‘do’ components: The do and bar component together
implement the guarded command construct with two guards, in which the do component implements the iteration part (thedo odpart, including the evalu- ation of the disjunction of the two guards), and the bar component implements the choice part (thethen or thenpart of the command).
The do component, when activated through its passive port, first collects the disjunction of the value of all guards through a handshake on its active data port. When the value thus collected is true, it activates its active nonput port (to activate the selected command), and after completion starts a new evalua- tion cycle. When the value collected is false, the do component completes its operation by completing the handshake on the passive port.
in2 mux y dmx in1 mux x dmx bar do out ; 0 1 2
Figure 8.9. Compiled handshake circuit for the GCD program using guarded repetition.
The bar component can be activated either through its passive data port, or through its passive control port. (The do component, for example, sequences these two activations.) When activated through the data port, it collects the value of two guards through a handshake on the active data ports, and then sends the disjunction of these values along the passive data port, thus complet- ing that handshake. When activated through the control port, the bar compo- nent activates an active control port of which the associated data port returned a ‘true’ value in the most recent data cycle. (For simplicity, this selection is typ- ically implemented in a deterministic fashion, although this is not required at the level of the program.) One may observe that bar components can be com-
bined in a tree or list to implement a guarded command list of arbitrary length. Furthermore, not every data cycle has to be followed by a control cycle.
The ‘mux’, ‘demux’, and ‘fork’ components The program for GCD in
figure 8.4 has two occurrences of variablexin which a value is written intox, namely input actionin1?x and assignment x:=x-y. In the handshake circuit of figure 8.9, these two write actions for Tangram variablexare merged by the multiplexer component so as to arrive at the write port of handshake variable x.
Variable x occurs at five different locations in the program as an expres- sion, once in the output expressionout!x, twice in the guard expressionsx<y andy<x, and twice in the assignment expressionsx-yandy-x. These five in- spections of variablexcould be implemented as five distinct read ports on the handshake variablex, which is shown in the handshake circuit in [135, Fig. 2.7, p.34]. In figure 8.9, a different compilation is shown, in which handshake vari- ablexhas three read ports:
A read port dedicated to the occurrence in the output action.
A read port dedicated to the guard expressions. Their evaluation is mu-
tually inclusive, and hence can be combined using a synchronizing fork
component.
A read port dedicated to the assignment expressions. Their evaluation is
mutually exclusive, and hence can be combined using a demultiplexer.
The GCD example is discussed in further detail in chapter 13.