This is an old revision of the document!
Simple combinational gates
The following specifies a number of combinational gates, where the process names correspond to the commonly used names for the gates.
defproc inverter (bool? i; bool! o) { prs { i => o- } } defproc nand2 (bool? a, b; bool! c) { prs { a & b => c- } } defproc nor2 (bool? a, b; bool! c) { prs { a | b => c- } }
While all the syntax should be familiar, this example also uses ,
to create multiple variables of the same type. For nand2
and nor2
, there are three variables in the port list. a
and b
have the same type (bool?
), whereas c
has a different type (bool!
).
If we wanted to create a two-input and gate, we could simply write:
defproc and2 (bool? a, b; bool! c) { prs { a & b => c+ } }
This would be accepted by ACT, and the production rule simulator prsim can simulate such rules without difficulty. However, a circuit designer would look at this and point out that we cannot implement this directly using a single pull-up and pull-down network in static CMOS. Instead, someone used to circuit design would write:
defproc and2 (bool? a, b; bool! c) { bool _c; prs { a & b => _c- _c => c- } }
In this example, we have introduced a local variable _c
. This variable is only visible within the process in the ACT language1). _c
is the output of a nand operation, and then it is inverted to generate the output c
.
Since we already have defined nand2
as well as inverter
, an alternative approach would be to re-use those circuits as follows:
defproc and2 (bool? a, b; bool! c) { bool _c; nand2 n(a,b,_c); inverter i(_c,c); }
Here, the body of and2
has three instances: _c
(a Boolean signal), n
(a nand2
), and i
(an inverter
). In addition, the syntax includes connections to the ports of both n
and i
.
In terms of naming, the ports of n
are n.a
, n.b
, and n.c
; similarly the ports for i
are i.i
and i.o
. ACT uses the dot as a hierarchy separator. This version of an and2
contains one level of hierarchy.
ACT provides a very flexible mechanism for connecting signals. The following a variants that correspond to the same connections.
defproc and2 (bool? a, b; bool! c) { bool _c; nand2 n; inverter i; n.a = a; n.b = b; n.c = _c; i.i = _c; i.o = c; }