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;
}
1)
Simulators typically give you access to any signal you wish to see to simplify debugging