Execution Logic

In a circuit a script can be defined in the property "Function" which is executed at "Flat simulation" instead of the circuit if the circuit is used as a subcircuit in another circuit.

When you write such a script, Antares will predefine all input and output pins of the circuit as implicit variable, so that you can access the signal at these pins simply by accessing those variables.

You write these scripts using the Antares DSL programming language.

Examples

Half Adder

This example shows the execution logic of a 1-bit half-adder with 2 inputs "A" and "B" and the outputs "S" (sum) and "C" (carry).

S = (A or B) and not (A and B)
C = A and B

Notice how the signals of the inputs are read, how logical operations are executed in Antares DSL, and how the results of these operations are set as output signals.

Incrementer

This example shows the execution logic of an 8-bit incrementer with data input "D" and the outputs "O" (data) and "CO" (carry out).

O = (D + 1) % 256
CO = D == 255

2-4 Decoder

This example shows the execution logic of a 2-4 decoder with two 1-bit data inputs "I0" and "I1", one enable input "EN" and 4 data outputs "O0".."O3". The decoder selects one of the 4 data outputs based on the 2-bit value at the two data inputs if "EN" is set.

val = I0 + 2 * I1
O0 = EN and val == 0
O1 = EN and val == 1
O2 = EN and val == 2
O3 = EN and val == 3

Note how the value of the "EN" input is used by the and operator to ensure that an output is only set to 1 if "EN" is also 1.

Undefined Gate Input Behaviour

Antares' system preference "Undefined Gate Input Behaviour" defines how gates behave with undefined (floating) input values. The default setting for this preference is "Read as O", meaning that a logic gate will treat an undefined signal at any of its outputs as 0.

When you write execution scripts for subcircuits, this logic is not applied per default, because the script engine can’t know which input pins are to be treated according to this logic, while others like data bus inputs must not.

Therefore, you can use the global DSL function gated() to apply the logic according to "Undefined Gate Input Behaviour" when accessing an input signal in an execution script.

For example, if you write a script for a "Multiplexer n Bit" subcircuit that is fully scripted, and you would like its output O to always be zero if the selection input or the selected input is undefined, you would write the script as follows:

if (gated(S)) {
  O = gated(B)
} else {
  O = gated(A)
}

See also Global DSL Functions for a description of this function.

Symbol Representation

In the symbol of a subcircuit scripting can be used to change the visualization of the symbol during simulation.

The possibilities for this are still rudimentary in the current version of Antares; future versions of Antares will provide more support here.

Use the property "Representation during simulation" in the symbol editor to define such a script for the symbol of a circuit.

External Functions

In addition to the variables Antares automatically declares to access all pins of the symbol, Antares also declares some functions you can use to adjust the graphical representation of the symbol.

/**
 * Draws a line in the correct signal color from an input pin to an output pin.
 * @param inputName the name of the input pin
 * @param outputName the name of the output pin
 */
private fun drawDataFlow(inputName: String, outputName: String)

/**
 * Sets the label of the symbol during execution. Only applicable if the symbol contains a label component.
 * @param label the current label text
 */
private fun setLabel(label: String)

Examples

Signal Flow

The example shows the representation logic of a multiplexer with two 4-bit inputs "A" and "B", a 1-bit selection input "S" (Select) and a 4-bit data output "O". Depending on the signal at the selection input, the resulting data flow from the selected input to the output is drawn.

if (S) drawDataFlow("B", "O") else drawDataFlow("A", "O")

Setting Labels

Changing symbol labels during simulation can be useful for complex subcircuits that perform a particular function depending on some control inputs. Examples of such circuits are ALUs or shifters.

During simulation, a user can more easily follow what a circuit is doing if such subcircuits indicate by their label what function they are currently performing.

The following example was taken from the ALU in the Tanenbaum example project. It supports 4 different arithmetic operations depending on the value of the control inputs F0 and F1.

when (2 * F1 + F0) {
    0 : setLabel("A+B")
    1 : setLabel("A and B")
    2 : setLabel("A")
    3 : setLabel("not A")
}