Cookbook

Creating a Two-Bit Output Counter

Application

This automaton creates a counter with two-bit output and carry out. (A two-bit counter counts 0, 1, 2, 3 and then it overflows and returns to 0.)

  • Each A symbol seen in the input data stream causes the counter to advance by one.
  • If an A causes the counter to overflow, it will be reflected in the output, and the counter starts again at 0.
  • When a # symbol is issued, the automaton reports the current count.

Construction

AP Workbench


Counter with two bit output and carry out

C Code

#include <micron/ap/ap_defs.h>
#include <micron/ap/ap_anml.h>

int main(int argc, char* argv[]) {
    ap_anml_t anml = NULL;
    ap_anml_network_t anml_net;
    struct ap_anml_element element = {0};
    ap_anml_element_ref_t a1, a2, a3, a4, b0, b1;

    // Initialize the automata network
    anml = AP_CreateAnml();
    AP_CreateAutomataNetwork(anml, &anml_net, "counter_with_2bit_display");

    // Build the network
    element.id = "a1";
    element.res_type = RT_STE;
    element.start = START_OF_DATA;
    element.symbols = "A";
    AP_AddAnmlElement(anml_net, &a1, &element);

    element.id = "a2";
    element.start = NO_START;
    AP_AddAnmlElement(anml_net, &a2, &element);

    element.id = "a3";
    AP_AddAnmlElement(anml_net, &a3, &element);

    element.id = "a4";
    element.match = 1;
    AP_AddAnmlElement(anml_net, &a4, &element);

    element.id = "b0";
    element.symbols = "#";
    element.match = 1;
    AP_AddAnmlElement(anml_net, &b0, &element);

    element.id = "b1";
    element.symbols = "#";
    element.match = 1;
    AP_AddAnmlElement(anml_net, &b1, &element);

    AP_AddAnmlEdge(anml_net, a1, b0, 0);
    AP_AddAnmlEdge(anml_net, a1, a2, 0);
    AP_AddAnmlEdge(anml_net, a2, b1, 0);
    AP_AddAnmlEdge(anml_net, a2, a3, 0);
    AP_AddAnmlEdge(anml_net, a3, b0, 0);
    AP_AddAnmlEdge(anml_net, a3, b1, 0);
    AP_AddAnmlEdge(anml_net, a3, a4, 0);
    AP_AddAnmlEdge(anml_net, a4, a1, 0);
    AP_AddAnmlEdge(anml_net, b0, a1, 0);
    AP_AddAnmlEdge(anml_net, b1, a1, 0);

    // Export the network to an ANML file
    AP_ExportAnml(anml_net, "counter_with_2bit_display.anml", "");

    // Clean up 
    AP_DestroyAnml(anml);
    return 0;
}

Python Code

from micronap.sdk import *

def main():
    # Initialize the automata network
    A = Anml()
    AN = A.CreateAutomataNetwork(anmlId='counter_with_2bit_display')

    # Build the network
    a1 = AN.AddSTE('A', startType=AnmlDefs.START_OF_DATA, anmlId='a1')
    a2 = AN.AddSTE('A', anmlId='a2')
    a3 = AN.AddSTE('A', anmlId='a3')
    a4 = AN.AddSTE('A', match=True, anmlId='a4')

    b0 = AN.AddSTE('#', match=True, anmlId='b0')
    b1 = AN.AddSTE('#', match=True, anmlId='b1')

    AN.AddAnmlEdge(a1, b0, 0)
    AN.AddAnmlEdge(a1, a2, 0)
    AN.AddAnmlEdge(a2, b1, 0)
    AN.AddAnmlEdge(a2, a3, 0)
    AN.AddAnmlEdge(a3, b0, 0)
    AN.AddAnmlEdge(a3, b1, 0)
    AN.AddAnmlEdge(a3, a4, 0)
    AN.AddAnmlEdge(a4, a1, 0)
    AN.AddAnmlEdge(b0, a1, 0)
    AN.AddAnmlEdge(b1, a1, 0)

    # Export the network to an ANML file
    AN.ExportAnml('counter_with_2bit_display.anml')

if __name__ == '__main__':
    main()

Operation

The binary reporting of this automaton is realized using two STEs: b0 and b1. These STEs represent the binary bit value of the bit position it is named for; that is, STE b0 reports if binary bit 0 of the two-bit counter is a 1, and STE b1 reports if binary bit 1 of the two-bit counter is a 1. If either of these bits is zero, the associated STE does not report.

For example, input A# causes only STE b0 to generate a report event. (STE b1 does not generate a report event.) Input AAA# causes both STE b0 and STE b1 to generate report events.

This design expects the input data stream to start with an A symbol. When the first A is seen, STE b0 is activated by STE a1. Therefore, if a # symbol is seen next, STE b0 generates a report event and STE b1 does not.

If the next symbol seen in the input data stream is another A, STE a2 will activate STE b1, but not STE b0. A third A in the input data stream will cause STE a3 to activate both STE b1 and STE b0. STE a4 is not connected to either b0 or b1; therefore, a fourth A in the input data stream will not cause any report activity if it is followed by a # symbol.

Each of the STEs that recognizes an A is connected to the next STE in sequence, with STE a4 connected back to STE a1 so that the cycle starts over again if four consecutive A symbols are seen in the input data stream. Additionally, STE a4 is set to generate a report event when the fourth A is processed, indicating an overflow condition has just occurred.

This design can easily be implemented into a three-bit or four-bit counter. However, with higher bit-value counters, more dense connections are required. At some point the capacity of the automaton network may be reached. The diagram for a four-bit counter is shown below. (Notice the heavier connection density in this design.)

Figure 1. Four-Bit Counter with Two-Bit Output and Carry Out
Counter with two bit output and carry out four bit