Cookbook

Reporting Occurrences of Exactly One Value

Application

This automaton generates a report event if one—and only one—occurrence of the target symbol is seen in the input data stream.

  • This automaton observes data from the beginning of the input data stream until the point when the end of data (EOD) signal is seen.
  • If the target symbol is not present in the input data stream, the automaton does not report.
  • If more than one occurrence of the target symbol is seen in the input data stream, the automaton does not report.
  • The report event is generated on the symbol cycle in which the EOD signal is seen.

Assumptions:

  • The target character is the letter a.

Construction

AP Workbench


Report occurrences exactly one value

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 q1, q2, q3, b1;

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

    // Build the network
    element.id = "q1";
    element.res_type = RT_STE;
    element.start = START_OF_DATA;
    element.symbols = "[^a]";
    element.match = 0;
    AP_AddAnmlElement(anml_net, &q1, &element);

    element.id = "q2";
    element.symbols = "a";
    AP_AddAnmlElement(anml_net, &q2, &element);

    element.id = "q3";
    element.start = NO_START;
    element.symbols = "[^a]";
    AP_AddAnmlElement(anml_net, &q3, &element);
    
    element.id = "b1";
    element.res_type = RT_BOOLEAN;
    element.bool_mode = BOOL_OR;
    element.eod = 1;
    element.terminals = 1;
    element.match = 1;
    AP_AddAnmlElement(anml_net, &b1, &element);

    AP_AddAnmlEdge(anml_net, q1, q1, 0);
    AP_AddAnmlEdge(anml_net, q1, q2, 0);
    AP_AddAnmlEdge(anml_net, q3, q3, 0);
    AP_AddAnmlEdge(anml_net, q2, q3, 0);
    AP_AddAnmlEdge(anml_net, q2, b1, BOOL_T1);
    AP_AddAnmlEdge(anml_net, q3, b1, BOOL_T1);

    // Export the network to an ANML file
    AP_ExportAnml(anml_net, "report_occurrences_of_exactly_one.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='report_occurrences_of_exactly_one')

    # Build the network
    q1 = AN.AddSTE('[^a]', startType=AnmlDefs.START_OF_DATA, anmlId='q1')
    AN.AddAnmlEdge(q1, q1, 0)

    q2 = AN.AddSTE('a', startType=AnmlDefs.START_OF_DATA, anmlId='q2')
    AN.AddAnmlEdge(q1, q2, 0)

    q3 = AN.AddSTE('[^a]', anmlId='q3')
    AN.AddAnmlEdge(q3, q3, 0)
    AN.AddAnmlEdge(q2, q3, 0)

    b1 = AN.AddBoolean(mode=BooleanMode.OR, eod=True, match=True, anmlId='b1')
    AN.AddAnmlEdge(q2, b1, AnmlDefs.T1_PORT)
    AN.AddAnmlEdge(q3, b1, AnmlDefs.T1_PORT)

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

if __name__ == '__main__':
    main()

Operation

This automaton starts operating one of two ways: if the first symbol seen by the automaton is an a or if the first symbol seen by the automaton is something other than an a.

In the second scenario (first symbol in the input data stream is anything other than an a), STE q1 will match because it is set to be active on the first symbol cycle. STE q1 will also self-activate, and thus, continue to be active as long as non-a symbols are seen in the input data stream.

STE q1 also activates STE q2; therefore, when the first a is seen in the input data stream, STE q2 will match. When this occurs, STE q1 will no longer match and will transition to an inactive state, where it will remain from that point forward.

STE q2 activates an OR gate (boolean element). If the input data stream were to end immediately after the first a symbol, the OR gate would be triggered by the EOD signal and it would generate a report event.

If there are other symbols in the input data stream beyond the first a, STE q3 handles them. As long as these other symbols are non-a symbols, STE q3 will continue to activate both itself and the OR gate. If an a symbol is seen, STE q3 will not match and will go inactive. It will remain inactive from this point forward, and the design will effectively die-out as there are no active STEs, nor are there any activation signals that would activate any STEs in the design.

In the case where the data stream does start with an a symbol, STE q1 will not match, and it will be inactive thereafter. However, STE q2 will match, and the processing will proceed as outlined above.