Our goal here is the creation of a small network based on some very simple actors with inputs and outputs.
This tutorial is inspired by the Wikipedia CAL page. You can find many other examples there if you want to become more familiar with CAL language (actors, non determinism, etc) but keep in mind that Orcc supports only a subset of CAL known as RVC-CAL.
In this example, our programs is composed of 4 actors. First, an actor "Add" has two inputs and produce a single output token. The output is the sum of the two inputs. Inputs are feeded by two actors and the output is send to an other actor that prints the result.
First of all you need to create a new Orcc project in Eclipse (File > New > Other...). You can name it AddOrcc (for example).
Let's take good habits making a new package (File > New > Package):
Before building the network, you should implement each actor using RVC-CAL language. For each actor, you have to create a standard file in the right package, and assign a name according to the actor name you will create. For example, the first actor to implement have to be written in the file Add.cal.
package org.ietr.addorcc; actor Add () int(size=8) Input1, int(size=8) Input2 ==> int(size=8) Output: action Input1: [a], Input2: [b] ==> Output: [a + b] do println("Actor Add is adding " + a + " and " + b); end end
The source below is just here to simulate a dataflow that is the normal input for a RVC-CAL network as it is done for video decoders programming. Create a Data.cal file and copy this source in it. Actor1 et Actor2 will import this data file.
package org.ietr.addorcc; unit Data : int INPUT_SIZE = 5; int SRC1[INPUT_SIZE] = [ 1, 2, 3, 4, 5 ]; int SRC2[INPUT_SIZE] = [ 1, 2, 3, 4, 5 ]; end
package org.ietr.addorcc; import org.ietr.addorcc.Data.SRC1; import org.ietr.addorcc.Data.INPUT_SIZE; actor Actor1 () ==> int(size=8) source1 : int i := 0; sendData: action ==> source1:[ Out ] guard i < INPUT_SIZE var uint(size=8) Out do Out := SRC1[i]; i := i+1; end end
package org.ietr.addorcc; import org.ietr.addorcc.Data.SRC2; import org.ietr.addorcc.Data.INPUT_SIZE; actor Actor2 () ==> int(size=8) source2 : int i := 0; sendData: action ==> source2:[ Out ] guard i < INPUT_SIZE var uint(size=8) Out do Out := SRC2[i]; i := i+1; end end
package org.ietr.addorcc; actor Actor3 () int(size=8) result ==> : action result:[a] ==> do println("The result is " + a); end end
As we explain before, we want to build a network that looks like that:
So you have to create a new Orcc Network (File > New > Other...):
Try to reproduce the network using the palette on the right of the network editor. Each Instance have to be associated to an actor or a subnetwork. To do so, right-click on an instance and select Set/Update refinement. Then, select the actor you want to associate with the instance. You can also drag and drop an actor from the project explorer to the network to automatically create a refined instance in your network. Please note that this feature works only if the actor is not currently opened in another tab in Eclipse.
To create connections between instances, click on an instance's output port, maintain the click and drag to the input port of another instance. If the connection can be created, it appears immediatly. The old way to create a connection is also supported: simply select Connections > Connection in the palette on right side of the editor, and create a connection between 2 ports.
So you are ready to run your network! The easiest way to see something is to run it as a simulation. Right-click on the XDF file and Run As > Orcc simulation.
In the Select simulator window, click OK.
In the Select input stimulus, select a random file and click VALIDATE (anyway it will not be used by our example).
Normaly you'll see this wizard:
Click RUN. In Eclipse conole, you should see something similar to:
As you can see, print actions from actor Add are all executed before print actions from Actor3. If you're used to sequential programming you may be surprised.
RVC-CAL scheduler is a round-robin algorithm based on actor's actions runs (not time slices) feeded by a dataflow. The scheduling is based on inputs and outputs status for each actor and a FIFO list of actor's actions. In our case, FIFO default size is 512. That's why all actions from Add are executed before actions from Actor3.
You can try to change the FIFO size (Run As > Run configuration...) to 0 in (Compilation Options) tab:
Click RUN and you'll see a slightly different output in Eclipse's console:
The main goal of Orcc is to generate code so you may also want to run this tutorial as a compilation. Please follow steps described in this page to generate code (C backend should be good to begin), build it and run it!
And magic will happen!
Install Orcc from the update site http://orcc.sf.net/eclipse/
Whether you need (or want to offer) help or advice, or if you just want to discuss/chat about Orcc, feel free to contact us!
Most of the team is based in Europe, so you might expect people to be connected and answer mail during the day (GMT+1).