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;
}

The = operator is used to connect two variables. Since connections correspond to aliasing (once two Booleans are connected, they are the same signal as far as the circuit is concerned).

defproc and2 (bool? a, b; bool! c)
{
  bool _c;
  nand2 n(.a=a, .b=b, .c=_c);
  inverter i(.i=_c, .o=c);
}

Simulation with irsim

irsim requires a transistor-level netlist as input in the .sim format. To support this, ACT includes the prs2sim tool that automatically converts an ACT design into .sim and .al files for irsim. However, for this to work correctly, production rules must be CMOS-implementable (see prs2sim, prs2net, prs language documentation for details); the quick summary is that the first version of and2 that can be simulated with prsim but not irsim; the version with a nand and inverter can be simulated with both.

To simulate a circuit, you need a top-level instance. Here is a small self-contained example.

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

defproc nand2 (bool? a, b; bool! c)
{
  prs {
    a & b => c-
  }
}

defproc and2 (bool? a, b; bool! c)
{
  nand2 n(.a=a, .b=b);
  inverter i(.i=n.c, .o=c);  // note that we don't need the intermediate _c
}

and2 a;

If this is saved in test_and.act, then we can create test.sim and test.al files using:

% prs2sim test_and.act test

Note that irsim uses / as a hierarchy separator. So the signals in the design are a/a, a/b, a/n/c, etc. You can now simulate this in the standard way using irsim.

A simple irsim simulation would look like this (assuming an scmos30 technology).

% irsim scmos30 test.sim test.al

(Note that you can run irsim from the terminal window as well as from the magic window. Please run irsim from the terminal window.) This starts the simulation environment, uses simulation parameters from the file scmos30.prm (stored in a standard location), and reads in the .sim/.al file just created.

There are irsim tutorials online. For the and gate, you can run a simple simulation by the following sequence of irsim commands:

% ana a/a
% ana a/b
% ana a/c

This opens a waveform window, and displays the signals a/a, a/b, and a/c. ana is short for analyzer.

% h Vdd!
% l GND!

This says that Vdd! is high, and GND! is low. You need these commands to setup the power supplies.

% s

s runs the simulation for one step (you can set the step size with the stepsize command). Now you can use h/l to set the input and watch the output change.

You can also create a text file of irsim commands (highly recommended as a general practice), and then read it in to irsim with the @ command.

1)
Simulators typically give you access to any signal you wish to see to simplify debugging