This is an old revision of the document!


A simple inverter

ACT is used to describe a hierarchical collection of processes that together implement a circuit. Each process is an independent entity, and operates concurrently with all the other processes in the system. Circuits are also processes, and the physical implementation of two circuits operate concurrently.

An inverter is a very simple process that has a one-bit digital input and one bit digital output. The following specifies a process that corresponds to one inverter.

defproc inverter (bool? i; bool! o)
{ 
  prs {
    i -> o-
   ~i -> o+
  }
} 

Let's start with the statements

 i -> o-
~i -> o+

These statements are two production rules. (prs documentation). If you have designed asynchronous circuits, then this terminology should be familiar. A production rule behaves in the following way:

  • The left hand side is a Boolean expression
  • The right hand side is a signal transition
  • There is an arrow between the two
  • If the left hand side is true, then (after some delay) the right hand side is executed eventually

The ~ symbol is used to indicate negation; the + means set the signal high; the - means set the signal low.

In this example, the variables i and o are Booleans. It should be clear that the combination of those two rules corresponds to an inverter.

The left hand side for o+ is the Boolean expression for the pull-up network for o; the left hand side for o- is the Boolean expression for the pull-down network for o.

This is a combinational gate, which means either the pull-up or pull-down network is always conducting (alternatively, the OR of the Boolean expressions for the pull-up and pull-down is always true). In this case, the pull-up and pull-down networks are complements of each other, so you only need specify one. The arrow can be used so that one rule can be used to specify both the pull-up and pull-down network as follows:

defproc inverter (bool? i; bool! o)
{ 
  prs {
    i => o-
  }
} 

The prs { … } specifies the production rule body for the process. There are other bodies that can also be included, and they use different keywords instead of prs but the same basic structure.

The entire process is wrapped in the process definition. defproc is used to define a process. Here, we name the process inverter. The signals i and o are in the port list for the process, which means they can be accessed from outside the process. They are declared as bools (Booleans), and the ? means that i is an input, and the ! means that o is an output.

This fragment of ACT simply defines a process named inverter. To actually create an inverter, we have to instantiate the process. The defproc can be viewed as defining the inverter type. We can use inverter just like we used bool, and create an inverter called inv using the following:

inverter inv;