Functional Primitives

A functional primitive will typically read the value of new input particles, compute the value of new output particles, and produce new output particles with timestamps identical to those of the new inputs.

In the DE model of computation, a primitive is runnable (ready for execution), if any input porthole has a new event, and that event has the smallest timestamp of any pending event in the system. When the primitive fires, it may need to know which input or inputs contain the events that triggered the firing. An input porthole containing a new particle has the dataNew flag set by the scheduler. The primitive can check the dataNew flag for each input.

To see how this is done, consider the DE primitive Switch:

defprimitive
{
  name        { Switch }
  domain      { DE }
  desc
  {
    The function of this primitive is to pass an Input DS to one of the two
output ports.  The value of the "control" input determines
which output is to be enabled.  If the value of the
"control" input is zero, the input DS is placed on the
"falseOut" output port. The input DS is placed on the
"trueOut" output port for non-zero values of the
"control" input.
  }

  input
  {
    name { input }
    type { anytype }
    desc { " This is the DS to be placed on one of the two output ports." }
  }

  output
  {
    name { trueOut }
    type { =input }
    desc { " The input DS is placed on this port if the \"control\" input is non-zero." }
  }

  output
  {
    name { falseOut }
    type { =input }
    desc { " The input DS is placed on this port if the \"control\" input is equals zero." }
  }

  input
  {
    name { control }
    type { int }
    desc { " Value which sets the switch.  A zero value will cause the Input to be placed on the \"falseOut\" output port, otherwise  a non-zero value will cause the input to be placed on the \"trueOut\" output port." }
  }

  go
  {
    if (input.dataNew && control.dataNew)
    {
      Particle& tP = input.get();

      if (int(control.get()) == 0)
      {
        falseOut.put(arrivalTime) = tP;
      }
      else
      {
        trueOut.put(arrivalTime) = tP;
      }
    }
  }
}

The Switch primitive has two input ports input and control. When an event arrives at the input port, it routes the event to either the trueOut or the falseOut output port depending on the value of the last received control input. In the go method, the programmer has to check whether a new input event has arrived. If not, then the firing was triggered by a control input event, and there is nothing to do. If the input has new data, then its particle is read using the get method, as summarized in the table below. In addition, the most recent value from the control input is read. This value is used to determine which output should receive the data input.

Summary of methods of class InDEPort

Method

Description

Particle& operator %

get a particle from the porthole without reseting dataNew

void before (GenericPort& p)

simultaneous inputs here should be processed before those at p

int dataNew

flag indicating whether the porthole has new data

Particle& get ()

get a particle from the porthole and reset dataNew

void getSimulEvent ()

fetch a simultaneous event from the global event queue

int numSimulEvents ()

return the number of pending simultaneous events at this input

void triggers ()

indicate that the input does not trigger any immediate output events

void triggers (GenericPort& p)

indicate that the input triggers an immediate output on port p

Summary of methods of class OutDEPort

Method

Description

Particle& operator %

get the most recent particle from the porthole

Particle& put (double time)

get a new writable particle with the given timestamp

void sendData ()

flush output porthole data (generated by put) to the global event queue

There are three ways to access a particle from an input or output port. First, the programmer can use the % operator followed by an integer, which is equivalent to the same operator in the SDF domain. For example, control%0 returns the most recent particle from the control porthole. The second method, get, is specific to class InDEPort. It resets the dataNew member of the port as well as returning the most recent particle from an input port. If you need to reset the dataNew member of an input port after reading the newly arrived event (the more common case) you should use the get method instead of %0 operator. Alternatively, you can reset the dataNew flag explicitly using a statement like:

input.dataNew = FALSE;

The put method is specific to OutDEPort. It sets the timeStamp member of the port to the value given by its argument, and returns a reference to the most recent particle from an output port. Considering the line in the above example:

trueOut.put(arrivalTime) = tP;

This says that the particle tP is copied to the trueOut output port with timeStamp = arrivalTime. The programmer can send more than one output event to the same port by calling the put method repeatedly. A new particle is returned each time.