--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/*
+You should note the following:
+I haven't implemented all the link-out policies.
+You can give the SHIP a single cmd with up to four operations. For
+example, "ADD ZERO 0 SUBTRACT SIGN 1 MAX MAX 0". These will be done
+in left-to-right order.
+You can use any link-out policy with any operation, though some don't
+make much sense.
+*/
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class ArithmeticShip extends InterpreterShip {
+
+ private int link;
+
+ DataInbox A = new DataInbox(this, "A");
+ DataInbox B = new DataInbox(this, "B");
+ DataInbox cmd = new DataInbox(this, "cmd");
+ DataOutbox out = new DataOutbox(this, "out");
+
+ public ArithmeticShip(Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public enum Operation {
+ // NOTE: NOP is not to be used, but rather simply prevents other ops from using opcode 0
+ // This is so that we can detect the "end" of a command - when the command is all zero
+ NOP { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_NOP\n"); return 0; } },
+ ADD { int eval(int a, int b, int link) { return a + b + link; } },
+ SUBTRACT { int eval(int a, int b, int link) { return a - b + link; } },
+ COPY_A { int eval(int a, int b, int link) { return a + link; } },
+ COPY_B { int eval(int a, int b, int link) { return b + link; } },
+ SELECT { int eval(int a, int b, int link) { return ((link==1) ? b : a); } },
+ NEGATE_A { int eval(int a, int b, int link) { return -(a+link); } },
+ NEGATE_B { int eval(int a, int b, int link) { return -(b+link); } },
+ ABS_A { int eval(int a, int b, int link) { a+=link; return (a<0 ? -a : a); } },
+ ABS_B { int eval(int a, int b, int link) { b+=link; return (b<0 ? -b : b); } },
+ MAX { int eval(int a, int b, int link) { return (a>b ? a : b) + link; } },
+ MIN { int eval(int a, int b, int link) { return (a<b ? a : b) + link; } },
+ INC_A { int eval(int a, int b, int link) { return a+1+link; } },
+ INC_B { int eval(int a, int b, int link) { return b+1+link; } },
+ RESERVED1 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED0\n"); return 0; } },
+ RESERVED2 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED1\n"); return 0; } };
+
+
+
+ // Do arithmetic op represented by this constant
+ abstract int eval(int a, int b, int link);
+ public static Operation convertInt( int i ) {
+ return values()[i];
+ }
+ }
+
+ public enum LinkOutPolicy {
+ LINK_IN, ZERO, CARRY, SIGN, OLD_SIGN, OVERFLOW, MAX, MIN;
+ public static LinkOutPolicy convertInt( int i ) {
+ return values()[i];
+ }
+ }
+
+ private long savedCommand = 0;
+
+ public void service() {
+ if (!out.readyForDataFromShip()) return;
+ if (!A.dataReadyForShip()) return;
+ if (!B.dataReadyForShip()) return;
+
+ long command;
+
+ if (savedCommand != 0) {
+ command = savedCommand;
+ } else if (!cmd.dataReadyForShip()) {
+ return;
+ } else {
+ command = cmd.removeDataForShip();
+ }
+
+ int inA = A.removeDataForShip();
+ int inB = B.removeDataForShip();
+ int linkInPolicy = (int)(command & 0x1);
+ LinkOutPolicy linkOutPolicy = LinkOutPolicy.convertInt((int)((command >> 1) & 0x7));
+ Operation op = Operation.convertInt((int)((command >> 4) & 0xf));
+ int result = 0;
+
+ int oldLink = link;
+ if (op == Operation.SELECT) {
+ link = link ^ linkInPolicy; // LinkInPolicy = 1 mean flip the selection for the SELECT op.
+ } else {
+ link = link & linkInPolicy; // If linkInPolicy is zero, unset the link bit for the upcoming computation.
+ // NOTE: The final value of link will be computed after eval.
+ }
+
+ result = op.eval(inA, inB, link);
+
+ switch (linkOutPolicy) {
+ case LINK_IN:
+ link = oldLink;
+ break;
+ case ZERO:
+ link = (result == 0) ? 1 : 0;
+// link = 0;
+ break;
+ case SIGN:
+ link = (result >> 31) & 0x1;
+ break;
+ case MAX:
+ if (inA > inB) link = 1; else link = 0;
+ break;
+ case MIN:
+ if (inA < inB) link = 1; else link = 0;
+ break;
+ case CARRY:
+ case OLD_SIGN:
+ case OVERFLOW:
+ System.out.println("ERROR: non-implemented linkOutPolicy selected");
+ break;
+ default:
+ System.out.println("ERROR: Unknown linkOutPolicy selected");
+ break;
+ };
+ out.addDataFromShip(result);
+
+ savedCommand = command >> 8;
+
+// System.out.println("Link is now " + link);
+ }
+
+ public int resolveShipSpecificConstant(String shipSpecificData) {
+ String[] data = shipSpecificData.split("\\s");
+ int result = 0;
+
+ if ((data.length % 3) != 0) {
+ System.out.println("ERROR: ArithmeticShip received invalid ShipSpecificConstant");
+ }
+ for (int i = data.length - 1; i >= 2; i-=3) {
+ result <<= 8;
+ if (data[i].equals("1")) {
+ result |= 1;
+ }
+ for (LinkOutPolicy policy : LinkOutPolicy.values()) {
+ if (data[i-1].equals(policy.toString())) {
+ result |= (policy.ordinal() << 1);
+ }
+ }
+ for (Operation op : Operation.values()) {
+ if (data[i-2].equals(op.toString())) {
+ result |= (op.ordinal() << 4);
+ }
+ }
+ }
+ return result;
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class Counter extends InterpreterShip {
+
+ private int count = 0;
+
+ DataInbox load = new DataInbox(this, "load");
+ TokenInbox decrement = new TokenInbox(this, "decrement");
+ TokenOutbox zero = new TokenOutbox(this, "zero");
+
+ public Counter(Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public String getBalsaName() { return "counter"; }
+ public void service() {
+ if (!zero.readyForTokenFromShip()) return;
+ if (count==0 && load.dataReadyForShip()) {
+ count = load.removeDataForShip();
+ return;
+ }
+ if (count>0 && decrement.tokenReadyForShip()) {
+ decrement.removeTokenForShip();
+ count--;
+ if (count==0)
+ zero.addTokenFromShip();
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class DeMux extends InterpreterShip {
+
+ DataInbox inp = new DataInbox(this, "in");
+ DataInbox selp = new DataInbox(this, "select");
+ DataOutbox truep = new DataOutbox(this, "true");
+ DataOutbox falsep = new DataOutbox(this, "false");
+
+ public String getBalsaName() { return "demux"; }
+
+ public DeMux (Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (inp.dataReadyForShip() && selp.dataReadyForShip() &&
+ truep.readyForDataFromShip() && falsep.readyForDataFromShip()) {
+ int in = inp.removeDataForShip();
+ int sel = selp.removeDataForShip();
+ if (sel==0)
+ falsep.addDataFromShip(in);
+ else
+ truep.addDataFromShip(in);
+ }
+ }
+
+}
+
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class Dup extends InterpreterShip {
+
+ DataInbox in = new DataInbox(this, "in");
+ DataOutbox a = new DataOutbox(this, "a");
+ DataOutbox b = new DataOutbox(this, "b");
+
+ public String getBalsaName() { return "dup"; }
+
+ public Dup (Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (in.dataReadyForShip() && a.readyForDataFromShip() && b.readyForDataFromShip()) {
+ int data = in.removeDataForShip();
+ a.addDataFromShip(data);
+ b.addDataFromShip(data);
+ }
+ }
+
+}
+
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class Dup3 extends InterpreterShip {
+
+ DataInbox in = new DataInbox(this, "in");
+ DataOutbox a = new DataOutbox(this, "a");
+ DataOutbox b = new DataOutbox(this, "b");
+ DataOutbox c = new DataOutbox(this, "c");
+
+ public String getBalsaName() { return "dup3"; }
+
+ public Dup3 (Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (in.dataReadyForShip() && a.readyForDataFromShip() && b.readyForDataFromShip() && c.readyForDataFromShip()) {
+ int data = in.removeDataForShip();
+ a.addDataFromShip(data);
+ b.addDataFromShip(data);
+ c.addDataFromShip(data);
+ }
+ }
+
+}
+
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class DuplicatorShip extends InterpreterShip {
+
+ DataInbox in = new DataInbox(this, "in");
+ DataOutbox out0 = new DataOutbox(this, "out0");
+ DataOutbox out1 = new DataOutbox(this, "out1");
+ DataOutbox out2 = new DataOutbox(this, "out2");
+ DataOutbox out3 = new DataOutbox(this, "out3");
+
+ public DuplicatorShip (Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (in.dataReadyForShip() && out0.readyForDataFromShip() &&
+ out1.readyForDataFromShip() && out2.readyForDataFromShip() &&
+ out3.readyForDataFromShip()) {
+ int data = in.removeDataForShip();
+ out0.addDataFromShip(data);
+ out1.addDataFromShip(data);
+ out2.addDataFromShip(data);
+ out3.addDataFromShip(data);
+ }
+ }
+
+}
+
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class HomeworkCounter extends InterpreterShip {
+
+ private int count = -1;
+
+ TokenOutbox zero = new TokenOutbox(this, "zero");
+ TokenOutbox positive = new TokenOutbox(this, "positive");
+ DataInbox load = new DataInbox(this, "load");
+ TokenInbox ask = new TokenInbox(this, "ask");
+
+ public HomeworkCounter(Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (!zero.readyForTokenFromShip()) return;
+ if (!positive.readyForTokenFromShip()) return;
+ if (load.dataReadyForShip()) {
+ count = load.removeDataForShip();
+ return;
+ }
+ if (ask.tokenReadyForShip()) {
+ ask.removeTokenForShip();
+ if (count > 0) {
+ count--;
+ positive.addTokenFromShip();
+ } else if (count<=0) {
+ zero.addTokenFromShip();
+ }
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+
+import edu.berkeley.fleet.*;
+import java.util.*;
+import java.io.*;
+
+public class MemoryReadShip extends InterpreterShip {
+
+ boolean _loaded = false;
+ int _count = 0;
+ int _stride = 0;
+ int _addr = 0;
+
+ DataInbox addr = new DataInbox(this, "addr");
+ DataInbox stride = new DataInbox(this, "stride");
+ DataInbox count = new DataInbox(this, "count");
+ DataOutbox data = new DataOutbox(this, "data");
+ TokenOutbox done = new TokenOutbox(this, "done");
+
+ public MemoryReadShip(Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (_count > 0) {
+ if (!data.readyForDataFromShip()) return;
+ data.addDataFromShip(_addr>=getInterpreter().mem.length ? 0 : getInterpreter().mem[_addr]);
+ _count--;
+ _addr += _stride;
+ if (_count==0)
+ done.addTokenFromShip();
+ } else {
+ if (count.dataReadyForShip() &&
+ addr.dataReadyForShip() &&
+ stride.dataReadyForShip() &&
+ done.readyForTokenFromShip() &&
+ data.readyForDataFromShip()) {
+
+ _count = count.removeDataForShip();
+ _addr = addr.removeDataForShip();
+ _stride = stride.removeDataForShip();
+ }
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+
+import edu.berkeley.fleet.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Thomas Kho <tkho@eecs.berkeley.edu>
+ */
+public class MemoryWriteShip extends InterpreterShip {
+
+ int _count = 0;
+ int _stride = 0;
+ int _addr = 0;
+
+ DataInbox addr = new DataInbox(this, "addr");
+ DataInbox stride = new DataInbox(this, "stride");
+ DataInbox count = new DataInbox(this, "count");
+ DataInbox data = new DataInbox(this, "data");
+ TokenOutbox done = new TokenOutbox(this, "done");
+
+ public MemoryWriteShip(Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (_count > 0) {
+ if (!data.dataReadyForShip()) return;
+ //getInterpreter().writeMem(_addr, data.removeDataForShip());
+ _count--;
+ _addr += _stride;
+ if (_count==0)
+ done.addTokenFromShip();
+ } else {
+ if (count.dataReadyForShip() &&
+ addr.dataReadyForShip() &&
+ stride.dataReadyForShip() &&
+ done.readyForTokenFromShip() &&
+ data.dataReadyForShip()) {
+
+ _count = count.removeDataForShip();
+ _addr = addr.removeDataForShip();
+ _stride = stride.removeDataForShip();
+ }
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class MultiplierShip extends InterpreterShip {
+
+ private int link;
+
+ DataInbox A = new DataInbox(this, "A");
+ DataInbox B = new DataInbox(this, "B");
+ DataOutbox out0 = new DataOutbox(this, "out0");
+ DataOutbox out1 = new DataOutbox(this, "out1");
+
+ public MultiplierShip(Interpreter fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (!out0.readyForDataFromShip()) return;
+ if (!out1.readyForDataFromShip()) return;
+ if (!A.dataReadyForShip()) return;
+ if (!B.dataReadyForShip()) return;
+
+ long inA = (long)A.removeDataForShip();
+ long inB = (long)B.removeDataForShip();
+ long result = inA * inB;
+ int result0 = (int)(result >> 32);
+ int result1 = (int)(result & 0xffffffff);
+
+ out0.addDataFromShip(result0);
+ out1.addDataFromShip(result1);
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class Mux extends InterpreterShip {
+
+ DataInbox ap = new DataInbox(this, "a");
+ DataInbox bp = new DataInbox(this, "b");
+ DataInbox choicep = new DataInbox(this, "select");
+ DataOutbox out = new DataOutbox(this, "out");
+
+ public Mux(Interpreter fleet, String name) { super(fleet, name); }
+
+ public String getBalsaName() { return "mux"; }
+
+ public void service() {
+ if (ap.dataReadyForShip() && bp.dataReadyForShip() && choicep.dataReadyForShip()) {
+ int a = ap.removeDataForShip();
+ int b = bp.removeDataForShip();
+ int choice = choicep.removeDataForShip();
+ out.addDataFromShip(choice==0 ? a : b);
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class ScatterShip extends InterpreterShip {
+
+ DataInbox in = new DataInbox(this, "in");
+ Vector<DataOutbox> out = new Vector<DataOutbox>();
+
+ private int size = 2;
+ private int state = 0;
+
+ public ScatterShip(Interpreter fleet, String name) {
+ super(fleet, name);
+ init();
+ }
+
+ private boolean initialized = false;
+ private void init() {
+ for (int i = 0; i < size; i++) {
+ out.add(new DataOutbox(this, "out" + i));
+ }
+ initialized = true;
+ }
+
+ public void service() {
+ if (!initialized) init();
+ if (in.dataReadyForShip() && out.get(state).readyForDataFromShip()) {
+ out.get(state).addDataFromShip(in.removeDataForShip());
+ state = (state + 1) % size;
+ }
+ }
+
+ public int resolveShipSpecificConstant(String shipSpecificData) {
+ return 0;
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class Sort2 extends InterpreterShip {
+
+ DataInbox ap = new DataInbox(this, "a");
+ DataInbox bp = new DataInbox(this, "b");
+ DataOutbox min = new DataOutbox(this, "min");
+ DataOutbox max = new DataOutbox(this, "max");
+
+ public Sort2(Interpreter fleet, String name) { super(fleet, name); }
+
+ public String getBalsaName() { return "sort2"; }
+
+ public void service() {
+ if (ap.dataReadyForShip() && bp.dataReadyForShip()) {
+ int a = ap.removeDataForShip();
+ int b = bp.removeDataForShip();
+ max.addDataFromShip(Math.max(a,b));
+ min.addDataFromShip(Math.min(a,b));
+ }
+ }
+
+}